cancel
Showing results for 
Search instead for 
Did you mean: 

PSoC 5, 3 & 1 MCU

roboteux
New Contributor II

Hi,

I have a set of boards that use a 24MHz clock using PSOC 5LP, with bootloader, and my bootloadable application.

Due to an issue of stock, I will receive my next set of board with a 12MHz clock.

I can change the PSOC clock configuration, that's OK.

But I want my bootloadable application to work on both board. I can read an ID in the Falsh to know which board it is.
But is there a way to nicely overwrite the ClockSetup function that is called il cyfitter_cfg.c .

or to compile my version of this file instead of the one generated by cydsfit.exe ?

0 Likes
1 Solution
Len_CONSULTRON
Honored Contributor II

roboteux,

Yes. Under most circumstances you can manipulate the user defined clocks using API calls.

For example:  I have a user defined clock called Clock_1 @ 12 MHz.

Len_CONSULTRON_0-1622120187550.png

If you select the component's datasheet you will notice the following functions:

Clock_SetDivider()

Sets the divider of the clock and restarts the clock divider immediately.
Clock_SetDividerRegister()

Sets the divider of the clock and optionally restarts the clock divider immediately.
Clock_SetDividerValue() Sets the divider of the clock and restarts the clock divider immediately.
Clock_GetDividerRegister()
Gets the clock divider register value.
Clock_SetMode() Sets flags that control the operating mode of the clock.
Clock_SetModeRegister() Sets flags that control the operating mode of the clock.
Clock_GetModeRegister() Gets the clock mode register value.
Clock_ClearModeRegister() Clears flags that control the operating mode of the clock.
Clock_SetSource() Sets the source of the clock.
Clock_SetSourceRegister() Sets the source of the clock.
Clock_GetSourceRegister() Gets the source of the clock.
Clock_SetFractionalDividerRegister() Sets the fractional divider of the clock and restarts the clock divider immediately.
Clock_SetFractionalDividerRegister() Sets the fractional divider of the clock and restarts the clock divider immediately.
Clock_GetFractionalDividerRegister() Gets the fractional clock divider register value.


These functions allow you to query and change the divider values and the source of the clock component. (There are more functions such as Start() and Stop().)

The PLL is a little trickier.  There are API calls in the CyLib.c

I have provided to the forum a extensive project that manipulates most if not all the clock types available to the PSoC5.   This project was intended to allow for trimming of the IMO and ILO frequencies for significantly improved accuracy and/or manipulation.

This project also has custom calls to various clock control registers including the PLL to optimize the P and Q factors for a better UART comm baud rate fit.

Here is the link if you are interested: PSoC5-IMO-and-ILO-clock-trimming-Project 

Len
"Engineering is an Art. The Art of Compromise."

View solution in original post

0 Likes
7 Replies
Len_CONSULTRON
Honored Contributor II

roboteux,

Can you be more specific.  The 24MHz and 12 MHz are crystals using the ECO?

If you are using the ECO, there is no special ClockSetup I know of.

Is there an issue where you need to change the clock scaling factor based on the ECO clock?

There are other solutions if you can be more specific why you need to make clock adjustments.

Len
"Engineering is an Art. The Art of Compromise."
0 Likes
roboteux
New Contributor II

Hi,

it's an XO oscillator, so on the PSOC it's a digital PIN.
I've got one set of boards with the 24MHz oscillator, and the new one will have a 12MHz.

When I check the clockSetup generated by PsocCreator, there are 2 register that have a different value for the configuration.

 

on the 12MHz config there is :

CY_SET_XTND_REG16((void CYFAR *)(CYREG_CLKDIST_DCFG0_CFG0), 0x0001u);

...

CY_SET_XTND_REG16((void CYFAR *)(CYREG_FASTCLK_PLL_P), 0x0818u);

And on the 24MHz (well may be I've inverted the config, not sure)

CY_SET_XTND_REG16((void CYFAR *)(CYREG_CLKDIST_DCFG0_CFG0), 0x0000u);

...

CY_SET_XTND_REG16((void CYFAR *)(CYREG_FASTCLK_PLL_P), 0x0520u);

 

That's the only 2 changes in the clockSetup function generated by PSOCCreator.

I'm looking for a way to overload the clockSetup function without modifying the cyfitter_cfg.c, because PSOCCreator will regenerate this file and delete any modification I do to it.

 

Thanks for any help

 

 

0 Likes
Len_CONSULTRON
Honored Contributor II

roboteux,

I guess I'm trying to get a handle on your difficulty.   If you know which clock you have, you can have a special function in the very first lines of main() to scale the remaining frequencies used in your application.

If you don't know which clock you have, you need to determine it.  One way is to use the IMO at a known frequency (12 MHz for example) to compare the output of the XO to know if it is 1x IMO or 2x IMO.

Len
"Engineering is an Art. The Art of Compromise."
0 Likes
roboteux
New Contributor II

Hi, I know which clock I have on the board (it will be written in my bootloader area). 

So yes I could boot assuming a 24 MHz clock, and then increase the PLL in my main if I have a 12 Mhz clock

But is there any trick to reprogram the clock. 

I suppose I must switch to an internal clock first, then disable the PLL, then configure the register, reenable the PLL, wait for it to lock, and then switch the clock. 

Is there any API the manipulate the clocks and the PLL ? 

0 Likes
Len_CONSULTRON
Honored Contributor II

roboteux,

Yes. Under most circumstances you can manipulate the user defined clocks using API calls.

For example:  I have a user defined clock called Clock_1 @ 12 MHz.

Len_CONSULTRON_0-1622120187550.png

If you select the component's datasheet you will notice the following functions:

Clock_SetDivider()

Sets the divider of the clock and restarts the clock divider immediately.
Clock_SetDividerRegister()

Sets the divider of the clock and optionally restarts the clock divider immediately.
Clock_SetDividerValue() Sets the divider of the clock and restarts the clock divider immediately.
Clock_GetDividerRegister()
Gets the clock divider register value.
Clock_SetMode() Sets flags that control the operating mode of the clock.
Clock_SetModeRegister() Sets flags that control the operating mode of the clock.
Clock_GetModeRegister() Gets the clock mode register value.
Clock_ClearModeRegister() Clears flags that control the operating mode of the clock.
Clock_SetSource() Sets the source of the clock.
Clock_SetSourceRegister() Sets the source of the clock.
Clock_GetSourceRegister() Gets the source of the clock.
Clock_SetFractionalDividerRegister() Sets the fractional divider of the clock and restarts the clock divider immediately.
Clock_SetFractionalDividerRegister() Sets the fractional divider of the clock and restarts the clock divider immediately.
Clock_GetFractionalDividerRegister() Gets the fractional clock divider register value.


These functions allow you to query and change the divider values and the source of the clock component. (There are more functions such as Start() and Stop().)

The PLL is a little trickier.  There are API calls in the CyLib.c

I have provided to the forum a extensive project that manipulates most if not all the clock types available to the PSoC5.   This project was intended to allow for trimming of the IMO and ILO frequencies for significantly improved accuracy and/or manipulation.

This project also has custom calls to various clock control registers including the PLL to optimize the P and Q factors for a better UART comm baud rate fit.

Here is the link if you are interested: PSoC5-IMO-and-ILO-clock-trimming-Project 

Len
"Engineering is an Art. The Art of Compromise."

View solution in original post

0 Likes
roboteux
New Contributor II

Thanks, change the PLL in the main seems to be the way to go. I've found the need API in Cylib.c (I havn't tested it yet). I'm thinking of may be measuring my crystal using the the number of ticks of the IMO, during a set period.

0 Likes
roboteux
New Contributor II

To conclude this topic here is what I've done :

int main(void)
{
#ifdef CRYSTAL_12MHz
CyMasterClk_SetSource(CY_MASTER_SOURCE_IMO);
CyPLL_OUT_Stop() ;
CY_SET_XTND_REG16((void CYFAR *)(CYREG_FASTCLK_PLL_P), 0x0520u);
CyPLL_OUT_Start(1) ;
CyMasterClk_SetSource(CY_MASTER_SOURCE_PLL);
#endif

 

in PSOC_CREATOR my external input is declared as 24MHz, and if I have a 12MHz oscillator on board, then the board boots at a 2 time slower speed. Then I execute my code to double the speed.
in PSOC_creator I've entered the correct CPU speed, so all the clock and setting (for the flash), are correct for my faster PLL.

I have a similar code in my bootloadable, that read the bootloader version to decide to apply or not the PLL speed change.

0 Likes