This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

Compiler/MSP430FR5848: Incorrect CRC from CRC module after SWPOR

Part Number: MSP430FR5848

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?

**Attention** This is a public forum