Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Cannot set Clock to 24 MHz #2

Open
yahaggach opened this issue Jun 15, 2024 · 7 comments
Open

Cannot set Clock to 24 MHz #2

yahaggach opened this issue Jun 15, 2024 · 7 comments

Comments

@yahaggach
Copy link

Hey there ,

First, thanks a lot :) If I can tip you some coffee let me know where !

I have an issue btw with setting the clock to the full 24 MHz using the internal RCH clock. I looked at the code and saw that prescaler being DIV1 does nothing for both PCLK and HCLK is that normal ?

@IOsetting
Copy link
Owner

Thank you for pointing out, I have submitted a fix 34c200e

Invoking Clk_Init(ClkFreq24Mhz, ClkDiv1, ClkDiv1) will set the clock to 24MHz, what kind of issue did you met?

@yahaggach
Copy link
Author

yahaggach commented Jun 15, 2024

Thank you for the quick reply.
It still doesn't work for some weird reason. Here is my main code :

`
#include "ddl.h"
#include "gpio.h"
#include "base_timer.h"
#include "clk.h"

#define LED_PIN (1) // Change this to the actual pin connected to your LED
#define LED_PORT (0) // Change this to the actual port connected to your LED

int main(void)
{
Clk_Init(ClkFreq24Mhz, ClkDiv1, ClkDiv1);
Gpio_InitIOExt(LED_PORT, LED_PIN, GpioDirOut, FALSE, FALSE, FALSE, FALSE);

while (1)
{
	GPIO_SetPinOutLow(LED_PORT, LED_PIN);
	__NOP();
	GPIO_SetPinOutHigh(LED_PORT, LED_PIN);
	__NOP();

}

}

`

I am monitoring with a logic analyzer the P01 port and here is what I see :

image

My goal is to evaluate the duration of the __NOP() function in an attempt to recreate the factory app that you can find in the T-HC32 repository (since I am using that evaluation board) in order to control a WS2812 led. I expect that this code should yield consistant 50% duty cycle square wave with the pulse width being approx. the duration of NOP + whatever overhead writing the to the GPIO port and having the level change... What is weird in the picture above is that :

1- The pulse low width seems to be approx. 4 MHz. Would that equate to the NOP duration ? That would be the case if the clock is 4 MHz which it is by default if i am not mistaken. I also expected much faster switching if the MCU really ran at 24 MHz.
2- The pulse high width seems to be equiv to approximately 2 MHz which is two times longer than the low pulse width. I tested and it is from the while loop looping which I find weird. If I put in my loop two times the code you see there successively then I get identical high and low width except for the last one which again turns to be twice longer....

So I am not really sure what is going on. It is not possible to do bitbanging of the WS2812 with pulses that are 0.2 us one needs much finer resolution in time. Am I getting something wrong ?

@yahaggach
Copy link
Author

Nevermind... I ran a code that basically pulses the gppio (basically go high then go low) and inserted in between N amount of NOP. I did it with one NOP and got a pulse width of 260 ns and did it with 3 NOP and got 340 ns which means that a NOP duration is indeed approx. 40 ns corresponding to 24MHz ... What surprises me is that the duration needed for turning a gpio high then low is necessarily 220 ns which seems a lot ... Is that normal ? We are only writing to a register to do that no ? Isn't that a single clock cycle op

@yahaggach
Copy link
Author

It seems that when working with such MCU one has really to go back to the basics. The macros are the reason why it takes 220 ns due to the pointer arithmetic inside... Direct port manipulation with hardcoded pointer

#define PORT1_OUT_REG *((volatile uint32_t *)((uint32_t)&M0P_GPIO->P1OUT))

I get approx. 90 ns per gpio operation meaning that the shortest pulse you can generate is approx. 180 ns with the M0+ at 24 MHz. I still have this weird issue that if I call successively :

PORT1_OUT_REG = 0x00;
PORT1_OUT_REG = 0x10;

The above statement holds true and I get N pulses based on N lines of code but If I do a standard

while (1)
{
PORT1_OUT_REG = 0x10;
PORT1_OUT_REG = 0x00;
}

I get a train of pulses of high width of 140 ns and low width of 280 ns. I understand that in a while loop the PC counter is incremented across the lines then reset but I wonder if that explains this huge discrepancy

@IOsetting
Copy link
Owner

http://efton.sk/STM32/gotcha/g14.html It's not a good idea to output accurate GPIO flips using software, you might need to use a timer or other peripherals to toggle a pin.

in order to control a WS2812 led

Using SPI to control WS2812 might be more feasible, please check this https://www.newinnovations.nl/post/controlling-ws2812-and-ws2812b-using-only-stm32-spi/, I have an example for PY32F0xx but I haven't migrated it to HC32L110.

@yahaggach
Copy link
Author

Yes I was aware of hardware being more consistent and faster because the mcu doesnt waste clock cycles there once it is setup. I still wanted to explore this and got to refresh my knowledge and that is thanks to your work :)

Still i realize that i come from MCUs like esp32 or the teensy with minimum 10 times higher performance so the thinking and logic with m0+ devices needs to be different. Do you have plans to implement the other examples ?

@IOsetting
Copy link
Owner

You are welcome~ So far, no, I am working on other projects, may not be able to play this chip for a while.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants