Tool/software: TI C/C++ Compiler
Hi there,
I have been experiencing an interesting phenomenon with producing a CRC after a SWPOR is triggered in the PMMCTL0 register.
If I perform a 'hard reset' over the debugger, the CRC I receive is as expected but if I perform only a soft reset, the CRC is consistently a different value.
This is the entry code:
#pragma CODE_SECTION(boot_crc16, ".section_u") #pragma FUNC_CANNOT_INLINE(boot_crc16) static void boot_crc16(volatile uint16_t* src, uint16_t len, volatile uint16_t* rCRC) { HWREG16(CRC_BASE + OFS_CRCINIRES) = 0xFFFF; uint16_t swp; do { swp = (*src >> 8) & 0xFF; swp |= (*src & 0xFF) << 8; HWREG16(CRC_BASE + OFS_CRCDIRB) = swp; src++; len--; } while(len > 0); *rCRC = HWREG16(CRC_BASE + OFS_CRCINIRES); } #pragma RETAIN(boot_entry) #pragma CODE_SECTION(boot_entry, ".section_u") #pragma FUNC_NEVER_RETURNS(boot_entry) #pragma FUNC_EXT_CALLED(boot_entry) void boot_entry(void) { // _op_code(0x4343); _delay_cycles(1500); /*!< is clock unstable at boot requiring a delay - if so, then is ram access also affected */ /// prepare the frame __asm(" .global __STACK_END"); __asm(" MOV.W #__STACK_END,SP"); __asm(" SUB.W #0x0400,SP"); { /*!< setup fram controller in the most safe fashion */ HWREG16(FRAM_BASE + OFS_FRCTL0) = (FRCTLPW | NWAITS_7); } { /*!< kill the watchdog */ HWREG16(WDT_A_BASE + OFS_WDTCTL) = (WDTPW | WDTHOLD); } { /*!< mpu setup */ HWREG16(MPU_BASE + OFS_MPUCTL0) = MPUPW | HWREG8(MPU_BASE + OFS_MPUCTL0); // unlock HWREG16(MPU_BASE + OFS_MPUSAM) = (MPUSEG1RE | MPUSEG1WE | MPUSEG2RE | MPUSEG2XE | MPUSEG3RE | MPUSEG3WE | MPUSEGIRE); // eeerw-r-xrw- HWREG16(MPU_BASE + OFS_MPUSEGB1) = ADDR16_TO_SEG_BORDER_BITS(SECTION_BOOT__START); // 0xa000 or 0x4400 HWREG16(MPU_BASE + OFS_MPUSEGB2) = ADDR16_TO_SEG_BORDER_BITS(SECTION_MAIN__START); // 0xa400 or 0x4800 HWREG16(MPU_BASE + OFS_MPUSAM) |= (MPUSEG1VS | MPUSEG2VS | MPUSEG3VS | MPUSEGIVS); // violation select HWREG16(MPU_BASE + OFS_MPUCTL0) = (MPUPW | HWREG8(MPU_BASE + OFS_MPUCTL0)) | MPUENA; // enable HWREG8(MPU_BASE + OFS_MPUCTL0_H) = 0x00; // lock } { /*!< clocks - 16MHz, dividers: 1, DCO for M/S and VLO for Aux, requests enabled */ HWREG16(CS_BASE + OFS_CSCTL0) = CSKEY; // password for access HWREG16(CS_BASE + OFS_CSCTL1) = (DCORSEL | DCOFSEL_4); // high-Speed | 16 MHz (possible to run at 24?) HWREG16(CS_BASE + OFS_CSCTL2) = (SELA_1 | SELS_3 | SELM_3); // ACLK -> VLOCLK, SMCLK -> DCOCLK, MCLK -> DCOCLK HWREG16(CS_BASE + OFS_CSCTL3) = (DIVA__1 | DIVS__1 | DIVM__1); // do not divide any clocks HWREG16(CS_BASE + OFS_CSCTL4) = (LFXTOFF | 1u << 8 | 0u << 3 | 0u<< 1); // LFXFT Off, HFXT Off, VLO On, SMCLK On HWREG16(CS_BASE + OFS_CSCTL5) = (0u << 7 | 0u << 6 | 0u << 1 | 0u << 0); // LFXT fault counter disabled, HFXT fault counter disabled, clear HFXTOF HWREG16(CS_BASE + OFS_CSCTL6) = (ACLKREQEN_L | SMCLKREQEN_L | MCLKREQEN_L) & ~(MODCLKREQEN_L); // Enable all conditional requests, except on MODCLK } { /*!< IO */ HWREG16(PMM_BASE + OFS_PM5CTL0) &= ~(LOCKLPM5); _bic_SR_register(CPUOFF); } { /*!< initialise debug uart */ /// setup debug output uart HWREG8(P2_BASE + OFS_P2SEL1) |= (BIT5 | BIT6); HWREG8(P2_BASE + OFS_P2SEL0) &= ~(BIT5 | BIT6); HWREG16(EUSCI_A1_BASE + OFS_UCAxCTLW0) |= (UCSWRST); // set SWRST (set automatically after PUC anyway) HWREG16(EUSCI_A1_BASE + OFS_UCAxCTLW0) = (UCSSEL1); // SMCLK (sources DCO CLK) HWREG16(EUSCI_A1_BASE + OFS_UCAxCTLW1) = (UCGLIT_3); // deglitch 200ns HWREG16(EUSCI_A1_BASE + OFS_UCAxBRW) = 0x0008; // 0x08 === 8 === (uint16_t)((16e6 / 115.2e3) / 16 ) (this is UCBRx) HWREG16(EUSCI_A1_BASE + OFS_UCAxMCTLW) = (0x00F7 << 8 | 0x000A << 4 | UCOS16); // 0xF7 from error calculation (this is UCBRSx[15:8] and UCBRFx [7:4]) HWREG16(EUSCI_A1_BASE + OFS_UCAxSTATW) = 0x0000; // clear all status, set listen disabled HWREG16(EUSCI_A1_BASE + OFS_UCAxABCTL) = 0x0000; // default autobaud disabled HWREG16(EUSCI_A1_BASE + OFS_UCAxIRCTL) = 0x0000; // disable IrDA HWREG16(EUSCI_A1_BASE + OFS_UCAxIFG) = 0x0000; // clear all flags (not necessary) HWREG16(EUSCI_A1_BASE + OFS_UCAxCTLW0) &= ~(UCSWRST); // start peripheral } { /*!< code */ volatile uint16_t pCRC; volatile uint16_t uCRC; boot_crc16(&HWREG16(SECTION_MAIN__START), SECTION_MAIN__SIZE, &pCRC); boot_crc16(&HWREG16(SECTION_UPDATE__START), SECTION_UPDATE__SIZE, &uCRC); _op_code(0x4343); /*!< breakpoint */ } }
At the manually placed breakpoint, I receive two different CRC's depending on if I used hard or soft reset.
If I manually pause for a large amount of time before the first crc16 is called, then the crc is accurage in both circumstances...
What's going on?