/****************************************************************************** * @fn HalOTAChkDL * * @brief Run the CRC16 Polynomial calculation over the DL image. * * @param None * * @return SUCCESS or FAILURE. */ uint8 HalOTAChkDL(uint8 dlImagePreambleOffset) { (void)dlImagePreambleOffset; // Intentionally unreferenced parameter uint32 oset; uint16 crc = 0; OTA_CrcControl_t crcControl; OTA_ImageHeader_t header; uint32 programStart; #if HAL_OTA_XNV_IS_SPI XNV_SPI_INIT(); #endif // Read the OTA File Header HalOTARead(0, (uint8 *)&header, sizeof(OTA_ImageHeader_t), HAL_OTA_DL); // Calculate the update image start address programStart = header.headerLength + OTA_SUB_ELEMENT_HDR_LEN; // Get the CRC Control structure HalOTARead(programStart + HAL_OTA_CRC_OSET, (uint8 *)&crcControl, sizeof(crcControl), HAL_OTA_DL); if ((crcControl.programSize > HAL_OTA_DL_MAX) || (crcControl.programSize == 0)) { return FAILURE; } // Run the CRC calculation over the downloaded image. for (oset = 0; oset < crcControl.programSize; oset++) { if ((oset < HAL_OTA_CRC_OSET) || (oset >= HAL_OTA_CRC_OSET+4)) { uint8 buf; HalOTARead(oset + programStart, &buf, 1, HAL_OTA_DL); crc = runPoly(crc, buf); } } return (crcControl.crc[0] == crc) ? SUCCESS : FAILURE; }
/****************************************************************************** * @fn dl2rc * * @brief Copy the DL image to the RC image location. * * NOTE: Assumes that DL image ends on a flash word boundary. * * @param None. * * @return None. */ static void dl2rc(void) { uint32 oset; OTA_SubElementHdr_t subElement; OTA_ImageHeader_t header; uint16 addr = HAL_OTA_RC_START / HAL_FLASH_WORD_SIZE; uint8 buf[4]; // Determine the length and starting point of the upgrade image HalOTARead(0, (uint8 *)&header, sizeof(OTA_ImageHeader_t), HAL_OTA_DL); HalOTARead(header.headerLength, (uint8*)&subElement, OTA_SUB_ELEMENT_HDR_LEN, HAL_OTA_DL); for (oset = 0; oset < subElement.length; oset += HAL_FLASH_WORD_SIZE) { HalOTARead(oset + header.headerLength + OTA_SUB_ELEMENT_HDR_LEN, buf, HAL_FLASH_WORD_SIZE, HAL_OTA_DL); if ((addr % (HAL_FLASH_PAGE_SIZE / HAL_FLASH_WORD_SIZE)) == 0) { HalFlashErase(addr / (HAL_FLASH_PAGE_SIZE / HAL_FLASH_WORD_SIZE)); } HalFlashWrite(addr++, buf, 1); } }
/****************************************************************************** * @fn dl2rc * * @brief Copy the DL image to the RC image location. * * NOTE: Assumes that DL image at least fills lower flash. * Assumes that DL image ends on a flash page boundary. * * @param None. * * @return None. */ static void dl2rc(void) { uint32 addr = DATA_OFFSET; uint32 addr2 = HI_ROM_BEG; uint16 *ptr; preamble_t preamble; uint16 buf; uint8 cnt = 0; vddWait(VDD_MIN_OTA); HalOTARead(DATA_OFFSET+PREAMBLE_OFFSET, (uint8 *)&preamble, sizeof(preamble_t), HAL_OTA_DL); FCTL3 = FWKEY; // Clear Lock bit. for (ptr = (uint16 *)LO_ROM_BEG; ptr <= (uint16 *)LO_ROM_END ; ) { FCTL1 = FWKEY + ERASE; // Set Erase bit. *ptr = 0; // Dummy write to erase Flash segment. FCTL1 = FWKEY + WRT; // Set WRT bit for write operation do { HalXNVRead(addr, (uint8 *)&buf, 2); *ptr++ = buf; addr += 2; } while (--cnt); // Wrap a uint8 once to count 256 * 2 = 512. } for (; addr < preamble.programLength+DATA_OFFSET; ) { FCTL1 = FWKEY + ERASE; // Set Erase bit. __data20_write_char(addr2,0); // Dummy write to erase Flash segment. FCTL1 = FWKEY + WRT; // Set WRT bit for write operation do { HalXNVRead(addr, (uint8 *)&buf, 2); __data20_write_short(addr2, buf); addr2 += 2; addr += 2; } while (--cnt); // Wrap a uint8 once to count 256 * 2 = 512. } FCTL1 = FWKEY; // Clear WRT bit FCTL3 = FWKEY + LOCK; // Set LOCK bit }
/****************************************************************************** * @fn crcCalc * * @brief Run the CRC16 Polynomial calculation over the RC image. * * @param None. * * @return The CRC16 calculated. */ static uint16 crcCalc() { uint32 oset; uint16 crc = 0; // Run the CRC calculation over the active body of code. for (oset = 0; oset < OTA_crcControl.programSize; oset++) { if ((oset < HAL_OTA_CRC_OSET) || (oset >= HAL_OTA_CRC_OSET + 4)) { uint8 buf; HalOTARead(oset, &buf, 1, HAL_OTA_RC); crc = runPoly(crc, buf); } } return crc; }
/****************************************************************************** * @fn HalOTARead * * @brief Read from the storage medium according to image type. * * @param oset - Offset into the monolithic image. * @param pBuf - Pointer to the buffer in which to copy the bytes read. * @param len - Number of bytes to read. * @param type - Which image: HAL_OTA_RC or HAL_OTA_DL. * * @return None. */ void HalOTARead(uint32 oset, uint8 *pBuf, uint16 len, image_t type) { if (HAL_OTA_RC != type) { #if HAL_OTA_XNV_IS_INT preamble_t preamble; HalOTARead(PREAMBLE_OFFSET, (uint8 *)&preamble, sizeof(preamble_t), HAL_OTA_RC); oset += HAL_OTA_RC_START + HAL_OTA_DL_OSET; #elif HAL_OTA_XNV_IS_SPI oset += HAL_OTA_DL_OSET; HalSPIRead(oset, pBuf, len); return; #endif } else { oset += HAL_OTA_RC_START; } HalFlashRead(oset / HAL_FLASH_PAGE_SIZE, oset % HAL_FLASH_PAGE_SIZE, pBuf, len); }
/****************************************************************************** * @fn crcCalc * * @brief Run the CRC16 Polynomial calculation over the RC image. * * @param None. * * @return The CRC16 calculated. */ static uint16 crcCalc(void) { preamble_t preamble; uint32 oset; uint8 *ptr; uint16 crc = 0; HalOTARead(PREAMBLE_OFFSET, (uint8 *)&preamble, sizeof(preamble_t), HAL_OTA_RC); preamble.programLength = HI_ROM_BEG + preamble.programLength - (LO_ROM_END - LO_ROM_BEG + 1); // Skipping 2-byte CRC and CRC shadow at the beginning of image. for (ptr = (uint8 *)LO_ROM_BEG+4; ptr <= (uint8 *)LO_ROM_END; ptr++) { crc = runPoly(crc, *ptr); } for (oset = HI_ROM_BEG; oset < preamble.programLength; oset++) { crc = runPoly(crc, __data20_read_char(oset)); } return crc; }