static inline void printPacket(Packet_t *p) { // PRINTF("%lu %d %d %d\n", p->timestamp, // p->acc_x, p->acc_y, p->acc_z); extFlashWrite(extFlashAddr, (uint8_t *) p, sizeof(*p)); extFlashAddr += sizeof(*p); }
bool processRCPacket(ReprogrammingContinuePacket_t *p) { // PRINTF("process RC packet\n"); if (p->imageId != currentImageId) { PRINTF("reprogramming: wrong image id (0x%x, expecting 0x%x)\n", p->imageId, currentImageId); return false; } const ExternalFlashBlock_t *fb = (ExternalFlashBlock_t *) &p->address; if (fb->crc != crc16((uint8_t *)fb, sizeof(*fb) - sizeof(uint16_t))) { PRINTF("reprogramming: wrong checksum\n"); return false; } uint32_t address = currentExtFlashStartAddress + 2 + p->blockId * sizeof(ExternalFlashBlock_t); // PRINTF("address=0x%x, id=%d\n", address, p->blockId); // write data and CRC SELECT_FLASH; extFlashWrite(address, fb, sizeof(*fb)); UNSELECT_FLASH; return true; }
void cleanFlash(void) { ledsSet(0xffff); extFlashBulkErase(); extFlashAddr = 0; // start with zeros extFlashWrite(extFlashAddr, (uint8_t *) &extFlashAddr, 4); extFlashAddr = 4; ledsSet(0x0); }
void readSensors(DataPacket_t *packet) { DPRINTF("reading sensors...\n"); ledOn(); humidityOn(); packet->timestamp = getJiffies(); packet->sourceAddress = localAddress; packet->dataSeqnum = ++dataSeqnum; if (localAddress != 0x0796) { if (!islRead(&packet->islLight, true)) { PRINT("islRead failed\n"); packet->islLight = 0xffff; } packet->sq100Light = 0xffff; } else { packet->islLight = 0xffff; if (!readAds(&packet->sq100Light)) { PRINT("readAdsRegister failed\n"); packet->sq100Light = 0xffff; } } packet->internalVoltage = adcRead(ADC_INTERNAL_VOLTAGE); packet->internalTemperature = adcRead(ADC_INTERNAL_TEMPERATURE); DPRINT("read hum\n"); packet->sht75Humidity = humidityRead(); packet->sht75Temperature = temperatureRead(); DPRINT("read done\n"); packet->crc = crc16((uint8_t *) packet, sizeof(*packet) - 2); #if WRITE_TO_FLASH if (extFlashAddress < EXT_FLASH_SIZE) { DPRINT("Writing to flash\n"); extFlashWrite(extFlashAddress, packet, sizeof(*packet)); DataPacket_t verifyRecord; memset(&verifyRecord, 0, sizeof(verifyRecord)); extFlashRead(extFlashAddress, &verifyRecord, sizeof(verifyRecord)); if (memcmp(packet, &verifyRecord, sizeof(verifyRecord))) { ASSERT("writing in flash failed!" && false); } extFlashAddress += sizeof(verifyRecord); } #endif humidityOff(); ledOff(); }
/******************************************************************************* * @fn SensorTag_saveFactoryImage * * @brief Save the current image to external flash as a factory image * * @return none */ static bool SensorTag_saveFactoryImage(void) { bool success; success = extFlashOpen(); if (success) { uint32_t address; // Erase external flash for (address= 0; address<EFL_FLASH_SIZE; address+=EFL_PAGE_SIZE) { extFlashErase(address,EFL_PAGE_SIZE); } // Install factory image for (address=0; address<EFL_SIZE_RECOVERY && success; address+=EFL_PAGE_SIZE) { success = extFlashErase(EFL_ADDR_RECOVERY+address, EFL_PAGE_SIZE); if (success) { size_t offset; static uint8_t buf[256]; // RAM storage needed due to SPI/DMA limitation for (offset=0; offset<EFL_PAGE_SIZE; offset+=sizeof(buf)) { const uint8_t *pIntFlash; // Copy from internal to external flash pIntFlash = (const uint8_t*)address + offset; memcpy(buf,pIntFlash,sizeof(buf)); success = extFlashWrite(EFL_ADDR_RECOVERY+address+offset, sizeof(buf), buf); // Verify first few bytes if (success) { extFlashRead(EFL_ADDR_RECOVERY+address+offset, sizeof(buf), buf); success = buf[2] == pIntFlash[2] && buf[3] == pIntFlash[3]; } } } } extFlashClose(); } return success; }
void processRSPacket(ReprogrammingStartPacket_t *p) { PRINTF("process RS packet, address=0x%lx\n", p->extFlashAddress); currentImageId = p->imageId; currentExtFlashStartAddress = p->extFlashAddress; currentImageBlockCount = p->imageBlockCount; SELECT_FLASH; // prepare flash to be written (one sector, i.e. 64k max!) extFlashEraseSector(p->extFlashAddress); // write image size extFlashWrite(p->extFlashAddress, &p->imageBlockCount, sizeof(uint16_t)); UNSELECT_FLASH; }
/******************************************************************************* * @fn saveImageInfo * * @brief Save image information in the meta-data area * * @return none */ void saveImageInfo(void) { uint32_t addr; if (imgInfo.imgType == EFL_OAD_IMG_TYPE_APP) { addr = EFL_IMAGE_INFO_ADDR_APP; } else { addr = EFL_IMAGE_INFO_ADDR_BLE; } // Erase old meta data. extFlashErase(addr, HAL_FLASH_PAGE_SIZE); // Set status so that bootloader pull in the new image. imgInfo.status = 0xFF; // Write new meta data. extFlashWrite(addr, sizeof(ExtImageInfo_t), (uint8_t*)&imgInfo); }
void flashWrite(uint32_t address) { extFlashWrite(address, buffer, BUFFER_SIZE); }
/********************************************************************* * @fn OADTarget_imgBlockWrite * * @brief Process the Image Block Write. * * @param connHandle - connection message was received on * @param pValue - pointer to data to be written * * @return status */ bStatus_t OADTarget_imgBlockWrite(uint16_t connHandle, uint8_t *pValue) { volatile uint16_t blkNum; blkNum = BUILD_UINT16(pValue[0], pValue[1]); // First block of OAD which included image header and CRC and CRC shadow // values. Do a sanity check on the received image header if (blkNum == 0) { img_hdr_t ImgHdr; uint16_t blkTot; blkTot = BUILD_UINT16(pValue[8], pValue[9]) / (OAD_BLOCK_SIZE / HAL_FLASH_WORD_SIZE); // Read out running image's header. uint8_t *flashAddr = (uint8_t *)(APP_IMAGE_START + OAD_IMG_HDR_OSET); memcpy(&ImgHdr,flashAddr,sizeof(img_hdr_t)); // Note: if additional customer criteria was checked in the Image // Identification step, it may be important to check again here. if ((oadBlkNum != blkNum) || (oadBlkTot != blkTot) ) { // Cancel download OADTarget_rejectImage(connHandle, &ImgHdr); // NB! This is meaningless for a WriteNoResp operation return (ATT_ERR_WRITE_NOT_PERMITTED); } #ifdef POWER_SAVING Power_setConstraint(Power_SB_DISALLOW); #endif } // Check that this is the expected block number. if (oadBlkNum == blkNum && flashOk) { uint32_t addr; // Calculate address to write as (start of OAD range) + (offset) addr = APP_IMAGE_START + oadBlkNum * OAD_BLOCK_SIZE; // If address starts a new page, erase that page first. if ((addr % HAL_FLASH_PAGE_SIZE) == 0) { flashOk = extFlashErase(addr, HAL_FLASH_PAGE_SIZE); } // Write a 16 byte block to Flash. if (flashOk) { flashOk = extFlashWrite(addr, OAD_BLOCK_SIZE, pValue+2); // Increment received block count. if (flashOk) oadBlkNum++; } // Toggle Green LED for every 8th block if ( (oadBlkNum % 8) == 0) { GPIO_toggle(Board_LED2); } } else { img_hdr_t ImgHdr; // Toggle RED LED and sound buzzer when overflow GPIO_toggle(Board_LED1); GPIO_toggle(Board_BUZZER); #ifdef POWER_SAVING Power_releaseConstraint(Power_SB_DISALLOW); #endif // Cancel download ImgHdr.len = 0; // Don't care content OADTarget_rejectImage(connHandle, &ImgHdr); } // Check if the OAD Image is complete. if (oadBlkNum == oadBlkTot) { extFlashClose(); // Run CRC check on new image. if (checkDL()) { HAL_SYSTEM_RESET(); } else { GPIO_toggle(Board_LED1); } #ifdef POWER_SAVING Power_releaseConstraint(Power_SB_DISALLOW); #endif } else { // Request the next OAD Image block. OADTarget_getNextBlockReq(connHandle, oadBlkNum); } return (SUCCESS); }
/********************************************************************* * @fn OADTarget_writeFlash * * @brief Write data to flash. * * @param page - page to write to in flash * @param offset - offset into flash page to begin writing * @param pBuf - pointer to buffer of data to write * @param len - length of data to write in bytes * * @return None. */ void OADTarget_writeFlash(uint8_t page, uint32_t offset, uint8_t *pBuf, uint16_t len) { extFlashWrite(FLASH_ADDRESS(page,offset), len, pBuf); }