USBDM Clock and ICS Clock Trimming

cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

USBDM Clock and ICS Clock Trimming

Jump to solution
1,470 Views
iansmusical
Contributor V

Hello All,

Up until recently I used a DEMOQE8 board but somehow the onboard P&E interface has died (posting on Freescale 8 bit forum), so I switched to my USBDM.


Has anyone successfully used the trim feature on the Connection tab of the USBDM Properties page? I've been trying to set 32.768KHz but the trim value that appears to be generated is 0x0.


On the DEMOQE8 board I was able to trim the internal clock within a debug session with ICSTRM = NVICSTRM without any problems but if I do the same thing via the USBDM it loses the connection and has to restart. Is there an option I have to set? (I realise a BDM will set the trim register to 0x80 but it should be able to be changed?)


Thanks,


Ian

0 Kudos
1 Solution
829 Views
pgo
Senior Contributor V

Hi Ian,

Just tried a DEMOQE8 with an external USBDM.

Creating a default project and enabling the trim but not changing the values from zero (which means use the target default value - very intuitive I know!) it produced the following result in the log window:

Starting 3rd party flash programming...

DiMemoryDownload() - DI_DNLD_TERMINATE - Programming memory image...

===========================================================

Programming target

    Device = 'MC9S08QE128'

  Trim, F=31250, NVA@FFAE, clock@0038

    Ram[0080...17FF]

    Erase=EraseMass

    Security=unsecured

    Total bytes=168

    doRamWrites=T

Erase Time = 1.26 s, Speed = 0.14 kBytes/s, rc = 0

FlashProgrammer::programFlash() - Device Trim Value = A4.0

Programming & verifying Time = 0.39 s, Speed = 0.47 kBytes/s, rc = 0

DiMemoryDownload() - DI_DNLD_TERMINATE - Programming complete, rc = 0

DiMemoryDownload() - DI_DNLD_TERMINATE - Resetting target

This indicates that it trimmed the target top 32250 Hz and stored the value at FFAE and FFAF.

The trim value calculated was A4.0 which means TRIM=A4 + FTRIM=0.

Manually setting the value to 31000Hz it produced a similar result (with a slightly different trim value):

pastedImage_13.png

Starting 3rd party flash programming...

DiMemoryDownload() - DI_DNLD_TERMINATE - Programming memory image...

===========================================================

Programming target

    Device = 'MC9S08QE128'

   Trim, F=31000, NVA@FFAE, clock@0038

    Ram[0080...17FF]

    Erase=EraseMass

    Security=unsecured

    Total bytes=168

    doRamWrites=T

Erase Time = 1.29 s, Speed = 0.14 kBytes/s, rc = 0

FlashProgrammer::programFlash() - Device Trim Value = A7.0

Programming & verifying Time = 0.39 s, Speed = 0.46 kBytes/s, rc = 0

DiMemoryDownload() - DI_DNLD_TERMINATE - Programming complete, rc = 0

DiMemoryDownload() - DI_DNLD_TERMINATE - Resetting target

Inspecting the two memory locations confirmed the values have been programmed to Flash.

pastedImage_10.png

I tested the trimming with the following minimal program:

#include <hidef.h> /* for EnableInterrupts macro */

#include "derivative.h" /* include peripheral declarations */

typedef unsigned char U8;

// Clock FTRIM values in Flash - value _combined_ with FTRIM bit by programmer

static const volatile U8 NV_FTRIM_INIT  @0x0000FFAE = 0xFF; // may be ICSSC_DRST_DRS0 etc

// Clock TRIM values in Flash - dummy value overwritten by flash programmer

static const volatile U8 NV_ICSTRM_INIT @0x0000FFAF = 0xFF;

void initClock( void ) {

   SOPT1          = SOPT1_STOPE_MASK|SOPT1_BKGDPE_MASK;  // Watchdog off, STOP enabled, BKGD pin enabled,

   if (NV_ICSTRM_INIT != 0xFF) {

     //  Only trim & update clock if Trim values have been programmed to Flash.

     //  Enabling x1 clock divider on untrimmed device may be out of bus clock spec.

     ICSSC       = NV_FTRIM_INIT;    // Trim the internal clock

     ICSTRM      = NV_ICSTRM_INIT;

     // Set 8/16 MHz bus clock assuming 31.25 MHz trim

     ICSC2 = (0<<ICSC2_BDIV_BITNUM);                   // BDIV=0,RANGE=0,HGO=0,LP=0,EREFS=0,ERCLKEN=0,EREFSTEN=0

     ICSC1 = (0<<ICSC1_CLKS_BITNUM)|ICSC1_IREFS_MASK;  // CLKS=0,RDIV=0,IREFS=1,IRCLKEN=0,IREFSTEN=0

   }

}

void main(void) {

  EnableInterrupts;

  /* include your code here */

  initClock();

  for(;;) {

    __RESET_WATCHDOG();    /* feeds the dog */

  } /* loop forever */

  /* please make sure that you never leave main */

}

I was able to program and debug the above program using Codewarrior 10.6 without any issues.

This included single-stepping through the clock code which can sometimes be problematic with changes in clock speed mid-step (affects the ACK).

Auto-connect should be enabled in the debug configuration (this is the default).

bye

PS This was with a MC9S08QE128.  I don't think you indicated if you are using a HCS08 or CFV1.

PPS.  The example above is from the USBDM Programmer manual.

PPPS.  After re-reading your post I suspect that you have overlooked that the trim value is a 9-bit number stored over two bytes.  Is is possible you are using the wrong byte?

View solution in original post

0 Kudos
4 Replies
829 Views
pgo
Senior Contributor V

Hi Ian,

You haven't indicated which version of Codewarrior you are using.

Trimming is NOT supported in Codewarrior V6.3.  The programming and trimming is actually done by Codewarrior itself and it doesn't actually do it for TBDML (which is what USBDM is emulating).

This is despite the trim tab.  There is nothing that can be done about this.

Trimming is (should be) possible in Codewarrior 10.x.  I haven't tested it lately so let me know if this is what you are talking about.

Trimming is also supported by the stand-alone programmers.

See this page for a description of USBDM capabilities.

USBDM: USBDM (combined TBDML/OSBDM code) for JS16

(or look in the manual)

bye.

0 Kudos
829 Views
iansmusical
Contributor V

Hi pgo,

Many thanks for your reply and indeed I should have stated that I'm using Codewarrior Eclipse 10.6 and version 4.10.6.160_win.

My steps were to click "enable trim" which then allowed me to enter a value in the trim field and the registers flash address but I noted that neither field was white and stayed grey when the "enable trim" was clicked. In the trim field I tried 32768 and 32.768 but on the latter it changed to 32.77.

I don't believe I use the stand-alone programmer as I usually just hit F11 in Codewarrior and let it flash the device.

Yes the JS16CWJ is used in my USBDM and states that it does support trimming. Could you point me to the manual as I haven't as yet found it!? I have since found the manual :-)

Are you able to answer point two regarding writing the trim value in a debug session? I saw that there is an option to auto reconnect the USBDM should clock changes occur?

Thanks,

Ian

0 Kudos
830 Views
pgo
Senior Contributor V

Hi Ian,

Just tried a DEMOQE8 with an external USBDM.

Creating a default project and enabling the trim but not changing the values from zero (which means use the target default value - very intuitive I know!) it produced the following result in the log window:

Starting 3rd party flash programming...

DiMemoryDownload() - DI_DNLD_TERMINATE - Programming memory image...

===========================================================

Programming target

    Device = 'MC9S08QE128'

  Trim, F=31250, NVA@FFAE, clock@0038

    Ram[0080...17FF]

    Erase=EraseMass

    Security=unsecured

    Total bytes=168

    doRamWrites=T

Erase Time = 1.26 s, Speed = 0.14 kBytes/s, rc = 0

FlashProgrammer::programFlash() - Device Trim Value = A4.0

Programming & verifying Time = 0.39 s, Speed = 0.47 kBytes/s, rc = 0

DiMemoryDownload() - DI_DNLD_TERMINATE - Programming complete, rc = 0

DiMemoryDownload() - DI_DNLD_TERMINATE - Resetting target

This indicates that it trimmed the target top 32250 Hz and stored the value at FFAE and FFAF.

The trim value calculated was A4.0 which means TRIM=A4 + FTRIM=0.

Manually setting the value to 31000Hz it produced a similar result (with a slightly different trim value):

pastedImage_13.png

Starting 3rd party flash programming...

DiMemoryDownload() - DI_DNLD_TERMINATE - Programming memory image...

===========================================================

Programming target

    Device = 'MC9S08QE128'

   Trim, F=31000, NVA@FFAE, clock@0038

    Ram[0080...17FF]

    Erase=EraseMass

    Security=unsecured

    Total bytes=168

    doRamWrites=T

Erase Time = 1.29 s, Speed = 0.14 kBytes/s, rc = 0

FlashProgrammer::programFlash() - Device Trim Value = A7.0

Programming & verifying Time = 0.39 s, Speed = 0.46 kBytes/s, rc = 0

DiMemoryDownload() - DI_DNLD_TERMINATE - Programming complete, rc = 0

DiMemoryDownload() - DI_DNLD_TERMINATE - Resetting target

Inspecting the two memory locations confirmed the values have been programmed to Flash.

pastedImage_10.png

I tested the trimming with the following minimal program:

#include <hidef.h> /* for EnableInterrupts macro */

#include "derivative.h" /* include peripheral declarations */

typedef unsigned char U8;

// Clock FTRIM values in Flash - value _combined_ with FTRIM bit by programmer

static const volatile U8 NV_FTRIM_INIT  @0x0000FFAE = 0xFF; // may be ICSSC_DRST_DRS0 etc

// Clock TRIM values in Flash - dummy value overwritten by flash programmer

static const volatile U8 NV_ICSTRM_INIT @0x0000FFAF = 0xFF;

void initClock( void ) {

   SOPT1          = SOPT1_STOPE_MASK|SOPT1_BKGDPE_MASK;  // Watchdog off, STOP enabled, BKGD pin enabled,

   if (NV_ICSTRM_INIT != 0xFF) {

     //  Only trim & update clock if Trim values have been programmed to Flash.

     //  Enabling x1 clock divider on untrimmed device may be out of bus clock spec.

     ICSSC       = NV_FTRIM_INIT;    // Trim the internal clock

     ICSTRM      = NV_ICSTRM_INIT;

     // Set 8/16 MHz bus clock assuming 31.25 MHz trim

     ICSC2 = (0<<ICSC2_BDIV_BITNUM);                   // BDIV=0,RANGE=0,HGO=0,LP=0,EREFS=0,ERCLKEN=0,EREFSTEN=0

     ICSC1 = (0<<ICSC1_CLKS_BITNUM)|ICSC1_IREFS_MASK;  // CLKS=0,RDIV=0,IREFS=1,IRCLKEN=0,IREFSTEN=0

   }

}

void main(void) {

  EnableInterrupts;

  /* include your code here */

  initClock();

  for(;;) {

    __RESET_WATCHDOG();    /* feeds the dog */

  } /* loop forever */

  /* please make sure that you never leave main */

}

I was able to program and debug the above program using Codewarrior 10.6 without any issues.

This included single-stepping through the clock code which can sometimes be problematic with changes in clock speed mid-step (affects the ACK).

Auto-connect should be enabled in the debug configuration (this is the default).

bye

PS This was with a MC9S08QE128.  I don't think you indicated if you are using a HCS08 or CFV1.

PPS.  The example above is from the USBDM Programmer manual.

PPPS.  After re-reading your post I suspect that you have overlooked that the trim value is a 9-bit number stored over two bytes.  Is is possible you are using the wrong byte?

0 Kudos
829 Views
iansmusical
Contributor V

Hi pgo,

Thank you for the detailed walk through, much appreciated. By using it I have been able to ascertain my error! Firstly, I assumed the dialog flash NVTRIM address required was 0xFFAF, corresponding to the 8 bit trim value but in fact it should have been flash address 0xFFAE, which is actually the fine trim value. Secondly, because the actual trim values were effectively off by one, when I tried to load the flash 8 bit trim value (from 0xFFAF) into the ICSTRM register I was actually writing a 0 (the calculated fine trim value), so that would have thrown the BDM clock off completely!!

So the problem is now solved thanks very much for your help :-)

Thanks,

Ian

0 Kudos