void bricklet_write_plugin_to_flash(const char *plugin, const uint8_t position, const uint8_t bricklet) { // Disable all irqs before plugin is written to flash. // While writing to flash there can't be any other access to the flash // (e.g. via interrupts). DISABLE_RESET_BUTTON(); __disable_irq(); // Unlock flash region FLASHD_Unlock(baddr[bricklet].plugin, baddr[bricklet].plugin + BRICKLET_PLUGIN_MAX_SIZE, 0, 0); // Write plugin to flash uint16_t add = position*PLUGIN_CHUNK_SIZE; FLASHD_Write(baddr[bricklet].plugin + add, plugin, PLUGIN_CHUNK_SIZE); // Lock flash and enable irqs again FLASHD_Lock(baddr[bricklet].plugin, baddr[bricklet].plugin + BRICKLET_PLUGIN_MAX_SIZE, 0, 0); __enable_irq(); ENABLE_RESET_BUTTON(); }
void bricklet_write_asc_to_flash(const uint8_t bricklet) { // Disable all irqs before plugin is written to flash. // While writing to flash there can't be any other access to the flash // (e.g. via interrupts). DISABLE_RESET_BUTTON(); __disable_irq(); // Unlock flash region FLASHD_Unlock(baddr[bricklet].plugin, baddr[bricklet].plugin + BRICKLET_PLUGIN_MAX_SIZE, 0, 0); // Write api address to flash int adr = (int)&ba; FLASHD_Write(baddr[bricklet].api, &adr, sizeof(int*)); // Write settings address to flash adr = (int)&bs[bricklet]; FLASHD_Write(baddr[bricklet].settings, &adr, sizeof(int*)); // Write context address to flash adr = (int)&bc[bricklet]; FLASHD_Write(baddr[bricklet].context, &adr, sizeof(int*)); // Lock flash and enable irqs again FLASHD_Lock(baddr[bricklet].plugin, baddr[bricklet].plugin + BRICKLET_PLUGIN_MAX_SIZE, 0, 0); __enable_irq(); ENABLE_RESET_BUTTON(); }
bool read_calibration_from_bno055_and_save_to_flash(void) { if(sensor_data.calibration_status != 0xFF) { return false; } bmo_write_register(REG_OPR_MODE, 0b00000000); // Configuration Mode SLEEP_MS(19); IMUCalibration imu_calibration = {{0}}; bmo_read_registers(REG_ACC_OFFSET_X_LSB, (uint8_t *)&imu_calibration, IMU_CALIBRATION_LENGTH); imu_calibration.password = IMU_CALIBRATION_PASSWORD; bmo_write_register(REG_OPR_MODE, 0b00001100); // Enable NDOF, see Table 3-5 SLEEP_MS(7); logimui("Read calibration from BNO055 and save to flash:\n\r"); logimui(" Mag Offset: %d %d %d\n\r", imu_calibration.mag_offset[0], imu_calibration.mag_offset[1], imu_calibration.mag_offset[2]); logimui(" Acc Offset: %d %d %d\n\r", imu_calibration.acc_offset[0], imu_calibration.acc_offset[1], imu_calibration.acc_offset[2]); logimui(" Gyr Offset: %d %d %d\n\r", imu_calibration.gyr_offset[0], imu_calibration.gyr_offset[1], imu_calibration.gyr_offset[2]); logimui(" Acc Radius: %d\n\r", imu_calibration.acc_radius); logimui(" Mag Radius: %d\n\r", imu_calibration.mag_radius); DISABLE_RESET_BUTTON(); __disable_irq(); // Unlock flash region if(FLASHD_Unlock(IMU_CALIBRATION_ADDRESS, END_OF_BRICKLET_MEMORY, NULL, NULL) != 0) { return false; } if(FLASHD_Write(IMU_CALIBRATION_ADDRESS, &imu_calibration, sizeof(IMUCalibration)) != 0) { return false; } if(FLASHD_Lock(IMU_CALIBRATION_ADDRESS, END_OF_BRICKLET_MEMORY, NULL, NULL) != 0) { return false; } __enable_irq(); ENABLE_RESET_BUTTON(); return true; }
/** * \brief Applet main entry. This function decodes received command and executes it. * * \param argc always 1 * \param argv Address of the argument area.. */ int main(int argc, char **argv) { struct _Mailbox *pMailbox = (struct _Mailbox *) argv; uint32_t bytesToWrite, bufferAddr, memoryOffset; uint32_t l_start, l_end; uint32_t *pActualStart = NULL; uint32_t *pActualEnd = NULL; uint8_t error ; uint32_t writeSize; /* Save info of communication link */ comType = pMailbox->argument.inputInit.comType; /*---------------------------------------------------------- * INIT: *----------------------------------------------------------*/ if (pMailbox->command == APPLET_CMD_INIT) { /* Re-configurate UART (MCK maybe change in LowLevelInit()) */ UART_Configure(115200, BOARD_MCK); /* Set 6 WS for internal Flash writing (refer to errata) */ EFC_SetWaitState(EFC0, 6); #if defined (EFC1) EFC_SetWaitState(EFC1, 6); #endif #if (DYN_TRACES == 1) dwTraceLevel = pMailbox->argument.inputInit.traceLevel; #endif flashBaseAddr = IFLASH_ADDR; flashBaseAddrInit = IFLASH_ADDR; flashSize = IFLASH_SIZE; flashPageSize = IFLASH_PAGE_SIZE; flashNbLockBits = IFLASH_NB_OF_LOCK_BITS; flashLockRegionSize = IFLASH_LOCK_REGION_SIZE; TRACE_INFO("-- Internal Flash SAM-BA Applet %s --\n\r", SAM_BA_APPLETS_VERSION); TRACE_INFO("-- %s\n\r", BOARD_NAME); TRACE_INFO("-- Compiled: %s %s --\n\r", __DATE__, __TIME__); /* Initialize flash driver */ FLASHD_Initialize(BOARD_MCK, 1); /* flash accesses must be 4 bytes aligned */ pMailbox->argument.outputInit.bufferAddress = ((uint32_t) &end); bufferSize = IRAM_SIZE /* sram size */ - ( ((uint32_t) &end) - IRAM_ADDR ) /* program size (romcode, code+data) */ - STACK_SIZE; /* stack size at the end */ /* integer number of pages can be contained in each buffer */ /* operation is : buffersize -= bufferSize % flashPageSize */ /* modulo can be done with a mask since flashpagesize is a power of two integer */ bufferSize = bufferSize > SECTOR_SIZE ? SECTOR_SIZE: bufferSize; pMailbox->argument.outputInit.bufferSize = bufferSize; pMailbox->argument.outputInit.memorySize = flashSize; pMailbox->argument.outputInit.memoryInfo.lockRegionSize = flashLockRegionSize; pMailbox->argument.outputInit.memoryInfo.numbersLockBits = flashNbLockBits; TRACE_INFO("bufferSize : %d bufferAddr: 0x%x \n\r", (int)pMailbox->argument.outputInit.bufferSize, (unsigned int) &end ); TRACE_INFO("memorySize : %d lockRegionSize : 0x%x numbersLockBits : 0x%x \n\r", (int)pMailbox->argument.outputInit.memorySize, (unsigned int)pMailbox->argument.outputInit.memoryInfo.lockRegionSize, (unsigned int)pMailbox->argument.outputInit.memoryInfo.numbersLockBits); pMailbox->status = APPLET_SUCCESS; } /*---------------------------------------------------------- * WRITE: *----------------------------------------------------------*/ else if (pMailbox->command == APPLET_CMD_WRITE) { memoryOffset = pMailbox->argument.inputWrite.memoryOffset; bufferAddr = pMailbox->argument.inputWrite.bufferAddr; bytesToWrite = pMailbox->argument.inputWrite.bufferSize; TRACE_INFO("WRITE at offset: 0x%x buffer at : 0x%x of: 0x%x Bytes (flash base addr : 0x%x)\n\r", (unsigned int)memoryOffset, (unsigned int)bufferAddr, (unsigned int)bytesToWrite, (unsigned int)flashBaseAddr); /* Check the giving sector have been locked before. */ if (FLASHD_IsLocked(flashBaseAddr + memoryOffset, flashBaseAddr + memoryOffset + bytesToWrite) != 0) { TRACE_INFO("Error page locked\n\r"); pMailbox->argument.outputWrite.bytesWritten = 0; pMailbox->status = APPLET_PROTECT_FAIL; goto exit; } if (memoryOffset % SECTOR_SIZE) { writeSize = SECTOR_SIZE - memoryOffset % SECTOR_SIZE; writeSize = writeSize > bufferSize ? bufferSize : writeSize; } else { writeSize = bytesToWrite; } TRACE_INFO("Write <%x> bytes from <#%x> \n\r", (unsigned int )writeSize, (unsigned int )memoryOffset ); l_start = memoryOffset / SECTOR_SIZE; if ((memoryOffset % SECTOR_SIZE == 0) || ((memoryOffset % SECTOR_SIZE != 0) && ( memoryOffset != (lastWrittenAddr + 1)))) { TRACE_INFO("Erase sector <#%d> \n\r", (unsigned int )l_start ); TRACE_INFO("Unlock from <#%x> to <#%x> for sector erasing \n\r", (unsigned int )(l_start * SECTOR_SIZE), (unsigned int)((l_start + 1) * SECTOR_SIZE -1)); FLASHD_Unlock(flashBaseAddr + l_start * SECTOR_SIZE, flashBaseAddr + (l_start + 1) * SECTOR_SIZE -1 , pActualStart, pActualEnd); #if defined (EFC1) if (memoryOffset < SECTOR_SIZE) { FLASHD_EraseSector(IFLASH_ADDR); /* Small sector 0: 8K */ FLASHD_EraseSector(IFLASH_ADDR + 1024 * 8); /* Small sector 1: 8K */ FLASHD_EraseSector(IFLASH_ADDR + 1024 * 16); /* Large sector : 48K */ } else if ((memoryOffset >= IFLASH_SIZE / 2) && (memoryOffset < (IFLASH_SIZE / 2 + SECTOR_SIZE))) { FLASHD_EraseSector(IFLASH_ADDR + IFLASH_SIZE / 2); /* Small sector 0: 8K */ FLASHD_EraseSector(IFLASH_ADDR + IFLASH_SIZE / 2 + 1024 * 8); /* Small sector 1: 8K */ FLASHD_EraseSector(IFLASH_ADDR + IFLASH_SIZE / 2 + 1024 * 16); /* Large sector : 48K */ } else { /* Common erase Other sectors */ FLASHD_EraseSector(flashBaseAddr + memoryOffset); } #else if (memoryOffset < SECTOR_SIZE) { FLASHD_EraseSector(IFLASH_ADDR); /* Small sector 0: 8K */ FLASHD_EraseSector(IFLASH_ADDR + 1024 * 8); /* Small sector 1: 8K */ FLASHD_EraseSector(IFLASH_ADDR + 1024 * 16); /* Large sector : 48K */ } else { /* Common erase Other sectors */ FLASHD_EraseSector(flashBaseAddr + memoryOffset); } #endif } /* Write data */ if (FLASHD_Write(flashBaseAddr + memoryOffset, (const void *)bufferAddr, writeSize) != 0) { TRACE_INFO("Error write operation\n\r"); pMailbox->argument.outputWrite.bytesWritten = writeSize ; pMailbox->status = APPLET_WRITE_FAIL; goto exit; } lastWrittenAddr = memoryOffset + writeSize - 1; TRACE_INFO("Write achieved\n\r"); pMailbox->argument.outputWrite.bytesWritten = writeSize; pMailbox->status = APPLET_SUCCESS; } /*---------------------------------------------------------- * READ: *----------------------------------------------------------*/ else if (pMailbox->command == APPLET_CMD_READ) { memoryOffset = pMailbox->argument.inputRead.memoryOffset; bufferAddr = pMailbox->argument.inputRead.bufferAddr; bufferSize = pMailbox->argument.inputRead.bufferSize; TRACE_INFO("READ at offset: 0x%x buffer at : 0x%x of: 0x%x Bytes (flash base addr : 0x%x)\n\r", (unsigned int)memoryOffset, (unsigned int)bufferAddr, (unsigned int)bufferSize, (unsigned int)flashBaseAddr); /* read data */ memcpy((void *)bufferAddr, (void *)(flashBaseAddr + memoryOffset), bufferSize); /* workaound for sam4s-xpld */ memcpy((void *)bufferAddr, (void *)(flashBaseAddr + memoryOffset), bufferSize); TRACE_INFO("Read achieved\n\r"); pMailbox->argument.outputRead.bytesRead = bufferSize; pMailbox->status = APPLET_SUCCESS; } /*---------------------------------------------------------- * FULL ERASE: *----------------------------------------------------------*/ else if (pMailbox->command == APPLET_CMD_FULL_ERASE) { TRACE_INFO("FULL ERASE command \n\r"); /* Check if at least one page has been locked */ if (FLASHD_IsLocked(flashBaseAddr, flashBaseAddr + flashSize) != 0) { TRACE_INFO("Error page locked \n\r"); pMailbox->status = APPLET_PROTECT_FAIL; goto exit; } /* Implement the erase all command */ /* Erase the flash */ if (FLASHD_Erase(flashBaseAddr) != 0) { TRACE_INFO("Flash erase failed! \n\r"); pMailbox->status = APPLET_ERASE_FAIL; goto exit; } #if defined (EFC1) /* Erase the flash1 */ if (FLASHD_Erase(flashBaseAddr + flashSize / 2) != 0) { TRACE_INFO("Full erase failed! \n\r"); pMailbox->status = APPLET_ERASE_FAIL; goto exit; } #endif lastWrittenAddr = 0; TRACE_INFO("Full erase achieved\n\r"); pMailbox->status = APPLET_SUCCESS; } /*---------------------------------------------------------- * LOCK SECTOR: *----------------------------------------------------------*/ else if (pMailbox->command == APPLET_CMD_LOCK) { TRACE_INFO("LOCK command \n\r"); l_start = (pMailbox->argument.inputLock.sector * flashLockRegionSize) + flashBaseAddr; l_end = l_start + flashLockRegionSize; if( FLASHD_Lock(l_start, l_end, pActualStart, pActualEnd) != 0) { TRACE_INFO("Lock failed! \n\r"); pMailbox->status = APPLET_PROTECT_FAIL; goto exit; } TRACE_INFO("Lock sector achieved\n\r"); pMailbox->status = APPLET_SUCCESS; } /*---------------------------------------------------------- * UNLOCK SECTOR: *----------------------------------------------------------*/ else if (pMailbox->command == APPLET_CMD_UNLOCK) { TRACE_INFO("UNLOCK command \n\r"); l_start = (pMailbox->argument.inputLock.sector * flashLockRegionSize) + flashBaseAddr; l_end = l_start + flashLockRegionSize; if( FLASHD_Unlock(l_start, l_end, pActualStart, pActualEnd) != 0) { TRACE_INFO("Unlock failed! \n\r"); pMailbox->status = APPLET_UNPROTECT_FAIL; goto exit; } TRACE_INFO("Unlock sector achieved\n\r"); pMailbox->status = APPLET_SUCCESS; } /*---------------------------------------------------------- * GPNVM : *----------------------------------------------------------*/ else if (pMailbox->command == APPLET_CMD_GPNVM) { if( pMailbox->argument.inputGPNVM.action == 0) { TRACE_INFO("DEACTIVATES GPNVM command \n\r"); error = FLASHD_ClearGPNVM(pMailbox->argument.inputGPNVM.bitsOfNVM); } else { TRACE_INFO("ACTIVATES GPNVM command \n\r"); error = FLASHD_SetGPNVM(pMailbox->argument.inputGPNVM.bitsOfNVM); } if(error != 0) { TRACE_INFO("GPNVM failed! \n\r"); pMailbox->status = APPLET_FAIL; goto exit; } TRACE_INFO("GPNVM achieved\n\r"); pMailbox->status = APPLET_SUCCESS; } /*---------------------------------------------------------- * READ UNIQUE ID : *----------------------------------------------------------*/ else if (pMailbox->command == APPLET_CMD_READ_UNIQUE_ID) { TRACE_INFO("READ UNIQUE ID command \n\r"); if (FLASHD_ReadUniqueID ((uint32_t *)(pMailbox->argument.inputReadUniqueID.bufferAddr)) != 0) { TRACE_INFO("Read Unique ID failed! \n\r"); pMailbox->status = APPLET_FAIL; goto exit; } TRACE_INFO("Read Unique ID achieved\n\r"); pMailbox->status = APPLET_SUCCESS; } exit: /* Acknowledge the end of command */ TRACE_INFO("\tEnd of Applet %x %x.\n\r", (unsigned int)pMailbox->command, (unsigned int)pMailbox->status); /* Notify the host application of the end of the command processing */ pMailbox->command = ~(pMailbox->command); if (comType == DBGU_COM_TYPE) { UART_PutChar(0x6); } return 0; }
/** * \brief Applet main entry. This function decodes received command and executes it. * * \param argc always 1 * \param argv Address of the argument area.. */ int main(int argc, char **argv) { struct _Mailbox *pMailbox = (struct _Mailbox *) argv; uint32_t bytesToWrite, bufferAddr, memoryOffset; uint32_t l_start, l_end; uint32_t *pActualStart = NULL; uint32_t *pActualEnd = NULL; uint8_t error; /* Disable watchdog */ WDT_Disable( WDT ) ; //TRACE_CONFIGURE_ISP(DBGU_STANDARD, 115200, BOARD_MCK); // ---------------------------------------------------------- // INIT: // ---------------------------------------------------------- if (pMailbox->command == APPLET_CMD_INIT) { // Save communication link type comType = pMailbox->argument.inputInit.comType; if (comType == DBGU_COM_TYPE){ USART_Configure(UART0, UART_MR_PAR_NONE, 115200, BOARD_MCK); USART_SetTransmitterEnabled(UART0, 1); USART_SetReceiverEnabled(UART0, 1); } flashBaseAddr = AT91C_IFLASH; flashBaseAddrInit = AT91C_IFLASH; flashSize = AT91C_IFLASH_SIZE; flashPageSize = AT91C_IFLASH_PAGE_SIZE; flashNbLockBits = AT91C_IFLASH_NB_OF_LOCK_BITS; flashLockRegionSize = AT91C_IFLASH_LOCK_REGION_SIZE; TRACE_INFO("-- Internal Flash Applet %s --\n\r", SAM_BA_APPLETS_VERSION); TRACE_INFO("-- %s\n\r", BOARD_NAME); TRACE_INFO("-- Compiled: %s %s --\n\r", __DATE__, __TIME__); // Initialize flash driver //FLASHD_Initialize(BOARD_MCK); // flash accesses must be 4 bytes aligned pMailbox->argument.outputInit.bufferAddress = ((uint32_t) &end); bufferSize = AT91C_ISRAM_SIZE // sram size - ( ((uint32_t) &end) - AT91C_ISRAM ) // program size (romcode, code+data) - STACK_SIZE; // stack size at the end // integer number of pages can be contained in each buffer // operation is : buffersize -= bufferSize % flashPageSize // modulo can be done with a mask since flashpagesize is a power of two integer bufferSize -= (bufferSize & (flashPageSize - 1)); pMailbox->argument.outputInit.bufferSize = bufferSize; pMailbox->argument.outputInit.memorySize = flashSize; pMailbox->argument.outputInit.memoryInfo.lockRegionSize = flashLockRegionSize; pMailbox->argument.outputInit.memoryInfo.numbersLockBits = flashNbLockBits; TRACE_INFO("bufferSize : %d bufferAddr: 0x%x \n\r", pMailbox->argument.outputInit.bufferSize, (uint32_t) &end ); TRACE_INFO("memorySize : %d lockRegionSize : 0x%x numbersLockBits : 0x%x \n\r", pMailbox->argument.outputInit.memorySize, pMailbox->argument.outputInit.memoryInfo.lockRegionSize, pMailbox->argument.outputInit.memoryInfo.numbersLockBits); pMailbox->status = APPLET_SUCCESS; } // ---------------------------------------------------------- // WRITE: // ---------------------------------------------------------- else if (pMailbox->command == APPLET_CMD_WRITE) { memoryOffset = pMailbox->argument.inputWrite.memoryOffset; bufferAddr = pMailbox->argument.inputWrite.bufferAddr; bytesToWrite = pMailbox->argument.inputWrite.bufferSize; TRACE_INFO("WRITE at offset: 0x%x buffer at : 0x%x of: 0x%x Bytes (flash base addr : 0x%x)\n\r", memoryOffset, bufferAddr, bytesToWrite, flashBaseAddr); // Check the giving sector have been locked before. if (FLASHD_IsLocked(flashBaseAddr + memoryOffset, flashBaseAddr + memoryOffset + bytesToWrite) != 0) { TRACE_INFO("Error page locked\n\r"); pMailbox->argument.outputWrite.bytesWritten = 0; pMailbox->status = APPLET_PROTECT_FAIL; goto exit; } // Write data if (FLASHD_Write(flashBaseAddr + memoryOffset, (const void *)bufferAddr, bytesToWrite) != 0) { TRACE_INFO("Error write operation\n\r"); pMailbox->argument.outputWrite.bytesWritten = 0; pMailbox->status = APPLET_WRITE_FAIL; goto exit; } TRACE_INFO("Write achieved\n\r"); pMailbox->argument.outputWrite.bytesWritten = bytesToWrite; pMailbox->status = APPLET_SUCCESS; } // ---------------------------------------------------------- // READ: // ---------------------------------------------------------- else if (pMailbox->command == APPLET_CMD_READ) { memoryOffset = pMailbox->argument.inputRead.memoryOffset; bufferAddr = pMailbox->argument.inputRead.bufferAddr; bufferSize = pMailbox->argument.inputRead.bufferSize; TRACE_INFO("READ at offset: 0x%x buffer at : 0x%x of: 0x%x Bytes (flash base addr : 0x%x)\n\r", memoryOffset, bufferAddr, bufferSize, flashBaseAddr); // read data memcpy((void *)bufferAddr, (void *)(flashBaseAddr + memoryOffset), bufferSize); TRACE_INFO("Read achieved\n\r"); pMailbox->argument.outputRead.bytesRead = bufferSize; pMailbox->status = APPLET_SUCCESS; } // ---------------------------------------------------------- // FULL ERASE: // ---------------------------------------------------------- else if (pMailbox->command == APPLET_CMD_FULL_ERASE) { TRACE_INFO("FULL ERASE command \n\r"); // Check if at least one page has been locked if (FLASHD_IsLocked(flashBaseAddr, flashBaseAddr + flashSize) != 0) { TRACE_INFO("Error page locked \n\r"); pMailbox->status = APPLET_PROTECT_FAIL; goto exit; } // Implement the erase all command if (FLASHD_Erase(flashBaseAddr) != 0) { TRACE_INFO("Full erase failed! \n\r"); pMailbox->status = APPLET_ERASE_FAIL; goto exit; } TRACE_INFO("Full erase achieved\n\r"); pMailbox->status = APPLET_SUCCESS; } // ---------------------------------------------------------- // LOCK SECTOR: // ---------------------------------------------------------- else if (pMailbox->command == APPLET_CMD_LOCK) { TRACE_INFO("LOCK command \n\r"); l_start = (pMailbox->argument.inputLock.sector * flashLockRegionSize) + flashBaseAddr; l_end = l_start + flashLockRegionSize; if( FLASHD_Lock(l_start, l_end, pActualStart, pActualEnd) != 0) { TRACE_INFO("Lock failed! \n\r"); pMailbox->status = APPLET_PROTECT_FAIL; goto exit; } TRACE_INFO("Lock sector achieved\n\r"); pMailbox->status = APPLET_SUCCESS; } // ---------------------------------------------------------- // UNLOCK SECTOR: // ---------------------------------------------------------- else if (pMailbox->command == APPLET_CMD_UNLOCK) { TRACE_INFO("UNLOCK command \n\r"); l_start = (pMailbox->argument.inputLock.sector * flashLockRegionSize) + flashBaseAddr; l_end = l_start + flashLockRegionSize; if( FLASHD_Unlock(l_start, l_end, pActualStart, pActualEnd) != 0) { TRACE_INFO("Unlock failed! \n\r"); pMailbox->status = APPLET_UNPROTECT_FAIL; goto exit; } TRACE_INFO("Unlock sector achieved\n\r"); pMailbox->status = APPLET_SUCCESS; } // ---------------------------------------------------------- // GPNVM : // ---------------------------------------------------------- else if (pMailbox->command == APPLET_CMD_GPNVM) { if( pMailbox->argument.inputGPNVM.action == 0) { TRACE_INFO("DEACTIVATES GPNVM command \n\r"); error = FLASHD_ClearGPNVM(pMailbox->argument.inputGPNVM.bitsOfNVM); } else { TRACE_INFO("ACTIVATES GPNVM command \n\r"); error = FLASHD_SetGPNVM(pMailbox->argument.inputGPNVM.bitsOfNVM); } if(error != 0) { TRACE_INFO("GPNVM failed! \n\r"); pMailbox->status = APPLET_FAIL; goto exit; } TRACE_INFO("GPNVM achieved\n\r"); pMailbox->status = APPLET_SUCCESS; } // ---------------------------------------------------------- // READ UNIQUE ID : // ---------------------------------------------------------- else if (pMailbox->command == APPLET_CMD_READ_UNIQUE_ID) { TRACE_INFO("READ UNIQUE ID command \n\r"); if (FLASHD_ReadUniqueID ((pMailbox->argument.inputReadUniqueID.bufferAddr)) != 0) { TRACE_INFO("Read Unique ID failed! \n\r"); pMailbox->status = APPLET_FAIL; goto exit; } TRACE_INFO("Read Unique ID achieved\n\r"); pMailbox->status = APPLET_SUCCESS; } exit: // Acknowledge the end of command TRACE_INFO("\tEnd of Applet %x %x.\n\r", pMailbox->command, pMailbox->status); // Notify the host application of the end of the command processing pMailbox->command = ~(pMailbox->command); if (comType == DBGU_COM_TYPE) { UART_PutChar(0x6); } return 0; }
//------------------------------------------------------------------------------ /// Applet main entry. This function decodes received command and executes it. /// \param argc always 1 /// \param argv Address of the argument area. //------------------------------------------------------------------------------ int main(int argc, char **argv) { struct _Mailbox *pMailbox = (struct _Mailbox *) argv; unsigned int bytesToWrite, bufferAddr, memoryOffset; unsigned int l_start; unsigned int l_end; unsigned int *pActualStart = NULL; unsigned int *pActualEnd = NULL; unsigned char error; TRACE_CONFIGURE_ISP(DBGU_STANDARD, 115200, BOARD_MCK); // ---------------------------------------------------------- // INIT: // ---------------------------------------------------------- if (pMailbox->command == APPLET_CMD_INIT) { // Save info of communication link comType = pMailbox->argument.inputInit.comType; #if (DYN_TRACES == 1) traceLevel = pMailbox->argument.inputInit.traceLevel; #endif switch (pMailbox->argument.inputInit.bank) { default: case 0: flashBaseAddr = AT91C_IFLASH; flashBaseAddrInit = AT91C_IFLASH; #if defined (at91sam3u4) flashSize = AT91C_IFLASH_SIZE + AT91C_IFLASH1_SIZE; #else flashSize = AT91C_IFLASH_SIZE; #endif flashPageSize = AT91C_IFLASH_PAGE_SIZE; pMailbox->argument.outputInit.memoryInfo.numbersLockBits = AT91C_IFLASH_NB_OF_LOCK_BITS; flashLockRegionSize = AT91C_IFLASH_LOCK_REGION_SIZE; break; #if defined (at91sam3u4) case 1: flashBaseAddr = AT91C_IFLASH1; flashBaseAddrInit = AT91C_IFLASH1; flashSize = AT91C_IFLASH1_SIZE; flashPageSize = AT91C_IFLASH1_PAGE_SIZE; pMailbox->argument.outputInit.memoryInfo.numbersLockBits = AT91C_IFLASH1_NB_OF_LOCK_BITS; flashLockRegionSize = AT91C_IFLASH1_LOCK_REGION_SIZE; break; #endif } TRACE_INFO("-- Internal Flash Applet %s --\n\r", SAM_BA_APPLETS_VERSION); TRACE_INFO("-- %s\n\r", BOARD_NAME); // Initialize flash driver FLASHD_Initialize(BOARD_MCK); // flash accesses must be 4 bytes aligned pMailbox->argument.outputInit.bufferAddress = ((unsigned int) &end); #if defined (at91sam7s161) || defined (at91sam3u1) bufferSize = flashPageSize * 2; #elif defined (at91sam7s32) || defined (at91sam7s321) || defined (at91sam7l) bufferSize = flashPageSize; #else bufferSize = AT91C_ISRAM_SIZE // sram size - ( ((unsigned int) &end) - AT91C_ISRAM ) // program size (romcode, code+data) - STACK_SIZE; // stack size at the end #endif // integer number of pages can be contained in each buffer // operation is : buffersize -= bufferSize % flashPageSize // modulo can be done with a mask since flashpagesize is a power of two integer bufferSize -= (bufferSize & (flashPageSize - 1)); if (bufferSize > MAX_BUF_SIZE && (comType == DBGU_COM_TYPE)) bufferSize = MAX_BUF_SIZE; pMailbox->argument.outputInit.bufferSize = bufferSize; pMailbox->argument.outputInit.memorySize = flashSize; pMailbox->argument.outputInit.memoryInfo.lockRegionSize = flashLockRegionSize; TRACE_INFO("bufferSize : %d bufferAddr: 0x%x \n\r", pMailbox->argument.outputInit.bufferSize, (unsigned int) &end ); TRACE_INFO("memorySize : %d lockRegionSize : 0x%x numbersLockBits : 0x%x \n\r", pMailbox->argument.outputInit.memorySize, pMailbox->argument.outputInit.memoryInfo.lockRegionSize, pMailbox->argument.outputInit.memoryInfo.numbersLockBits); pMailbox->status = APPLET_SUCCESS; } // ---------------------------------------------------------- // WRITE: // ---------------------------------------------------------- else if (pMailbox->command == APPLET_CMD_WRITE) { memoryOffset = pMailbox->argument.inputWrite.memoryOffset; bufferAddr = pMailbox->argument.inputWrite.bufferAddr; bytesToWrite = pMailbox->argument.inputWrite.bufferSize; #if defined (at91sam3u4) if (flashBaseAddrInit == AT91C_IFLASH) { if ((memoryOffset < AT91C_IFLASH_SIZE) && ((memoryOffset + bytesToWrite) > AT91C_IFLASH_SIZE)) { flashBaseAddr = AT91C_IFLASH; bytesToWrite = AT91C_IFLASH_SIZE - memoryOffset; } else if (memoryOffset >= AT91C_IFLASH_SIZE) { flashBaseAddr = AT91C_IFLASH1; memoryOffset -= AT91C_IFLASH_SIZE; } } #endif TRACE_INFO("WRITE at offset: 0x%x buffer at : 0x%x of: 0x%x Bytes (flash base addr : 0x%x)\n\r", memoryOffset, bufferAddr, bytesToWrite, flashBaseAddr); // Check the giving sector have been locked before. if (FLASHD_IsLocked(flashBaseAddr + memoryOffset, flashBaseAddr + memoryOffset + bytesToWrite) != 0) { TRACE_INFO("Error page locked\n\r"); pMailbox->argument.outputWrite.bytesWritten = 0; pMailbox->status = APPLET_PROTECT_FAIL; goto exit; } // Write data if (FLASHD_Write(flashBaseAddr + memoryOffset, (const void *)bufferAddr, bytesToWrite) != 0) { TRACE_INFO("Error write operation\n\r"); pMailbox->argument.outputWrite.bytesWritten = 0; pMailbox->status = APPLET_WRITE_FAIL; goto exit; } TRACE_INFO("Write achieved\n\r"); pMailbox->argument.outputWrite.bytesWritten = bytesToWrite; pMailbox->status = APPLET_SUCCESS; } // ---------------------------------------------------------- // READ: // ---------------------------------------------------------- else if (pMailbox->command == APPLET_CMD_READ) { memoryOffset = pMailbox->argument.inputRead.memoryOffset; bufferAddr = pMailbox->argument.inputRead.bufferAddr; bufferSize = pMailbox->argument.inputRead.bufferSize; #if defined (at91sam3u4) if (flashBaseAddrInit == AT91C_IFLASH) { flashBaseAddr = AT91C_IFLASH; if ((memoryOffset < AT91C_IFLASH_SIZE) && ((memoryOffset + bufferSize) > AT91C_IFLASH_SIZE)) { bufferSize = AT91C_IFLASH_SIZE - memoryOffset; } else if (memoryOffset >= AT91C_IFLASH_SIZE) { flashBaseAddr = AT91C_IFLASH1; memoryOffset -= AT91C_IFLASH_SIZE; } } #endif TRACE_INFO("READ at offset: 0x%x buffer at : 0x%x of: 0x%x Bytes (flash base addr : 0x%x)\n\r", memoryOffset, bufferAddr, bufferSize, flashBaseAddr); // read data memcpy((void *)bufferAddr, (void *)(flashBaseAddr + memoryOffset), bufferSize); TRACE_INFO("Read achieved\n\r"); pMailbox->argument.outputRead.bytesRead = bufferSize; pMailbox->status = APPLET_SUCCESS; } // ---------------------------------------------------------- // FULL ERASE: // ---------------------------------------------------------- else if (pMailbox->command == APPLET_CMD_FULL_ERASE) { TRACE_INFO("FULL ERASE command \n\r"); #if defined (at91sam3u4) if (flashBaseAddrInit == AT91C_IFLASH) { flashBaseAddr = AT91C_IFLASH; // Check if at least one page has been locked if (FLASHD_IsLocked(flashBaseAddr, flashBaseAddr + AT91C_IFLASH_SIZE - 1) != 0) { TRACE_INFO("Error page locked \n\r"); pMailbox->status = APPLET_PROTECT_FAIL; goto exit; } } else { // Check if at least one page has been locked if (FLASHD_IsLocked(flashBaseAddr, flashBaseAddr + AT91C_IFLASH1_SIZE - 1) != 0) { TRACE_INFO("Error page locked \n\r"); pMailbox->status = APPLET_PROTECT_FAIL; goto exit; } } #else // Check if at least one page has been locked if (FLASHD_IsLocked(flashBaseAddr, flashBaseAddr + flashSize) != 0) { TRACE_INFO("Error page locked \n\r"); pMailbox->status = APPLET_PROTECT_FAIL; goto exit; } #endif // Implement the erase all command if (FLASHD_Erase(flashBaseAddr) != 0) { TRACE_INFO("Full erase failed! \n\r"); pMailbox->status = APPLET_ERASE_FAIL; goto exit; } #if defined (at91sam7xc512) || (at91sam7x512) if (FLASHD_Erase(flashBaseAddr + FLASH_SECOND_BANK_OFFSET) != 0) { TRACE_INFO("Full erase failed! \n\r"); pMailbox->status = APPLET_ERASE_FAIL; goto exit; } #endif TRACE_INFO("Full erase achieved\n\r"); pMailbox->status = APPLET_SUCCESS; } // ---------------------------------------------------------- // LOCK SECTOR: // ---------------------------------------------------------- else if (pMailbox->command == APPLET_CMD_LOCK) { TRACE_INFO("LOCK command \n\r"); #if defined (at91sam3u4) if (flashBaseAddrInit == AT91C_IFLASH) { flashBaseAddr = AT91C_IFLASH; if (pMailbox->argument.inputLock.sector >= AT91C_IFLASH_NB_OF_LOCK_BITS) { flashBaseAddr = AT91C_IFLASH1; pMailbox->argument.inputLock.sector -= AT91C_IFLASH_NB_OF_LOCK_BITS; } } #endif l_start = (pMailbox->argument.inputLock.sector * flashLockRegionSize) + flashBaseAddr; l_end = l_start + flashLockRegionSize; if( FLASHD_Lock(l_start, l_end, pActualStart, pActualEnd) != 0) { TRACE_INFO("Lock failed! \n\r"); // ASSERT( *pActualStart == l_start, "-F- Lock failed! \n\r"); // ASSERT( *pActualEnd == (l_start + flashLockRegionSize), "-F- Lock failed! \n\r"); pMailbox->status = APPLET_PROTECT_FAIL; goto exit; } TRACE_INFO("Lock sector achieved\n\r"); pMailbox->status = APPLET_SUCCESS; } // ---------------------------------------------------------- // UNLOCK SECTOR: // ---------------------------------------------------------- else if (pMailbox->command == APPLET_CMD_UNLOCK) { TRACE_INFO("UNLOCK command \n\r"); #if defined (at91sam3u4) if (flashBaseAddrInit == AT91C_IFLASH) { flashBaseAddr = AT91C_IFLASH; if (pMailbox->argument.inputLock.sector >= AT91C_IFLASH_NB_OF_LOCK_BITS) { flashBaseAddr = AT91C_IFLASH1; pMailbox->argument.inputLock.sector -= AT91C_IFLASH_NB_OF_LOCK_BITS; } } #endif l_start = (pMailbox->argument.inputLock.sector * flashLockRegionSize) + flashBaseAddr; l_end = l_start + flashLockRegionSize; if( FLASHD_Unlock(l_start, l_end, pActualStart, pActualEnd) != 0) { TRACE_INFO("Unlock failed! \n\r"); //ASSERT( *pActualStart == l_start, "-F- Unlock failed! \n\r"); //ASSERT( *pActualEnd == (l_start + flashLockRegionSize), "-F- Unock failed! \n\r"); pMailbox->status = APPLET_UNPROTECT_FAIL; goto exit; } TRACE_INFO("Unlock sector achieved\n\r"); pMailbox->status = APPLET_SUCCESS; } // ---------------------------------------------------------- // GPNVM : // ---------------------------------------------------------- #if !defined (at91sam7a3) else if (pMailbox->command == APPLET_CMD_GPNVM) { if( pMailbox->argument.inputGPNVM.action == 0) { TRACE_INFO("DEACTIVATES GPNVM command \n\r"); error = FLASHD_ClearGPNVM(pMailbox->argument.inputGPNVM.bitsOfNVM); } else { TRACE_INFO("ACTIVATES GPNVM command \n\r"); error = FLASHD_SetGPNVM(pMailbox->argument.inputGPNVM.bitsOfNVM); } if(error != 0) { TRACE_INFO("GPNVM failed! \n\r"); pMailbox->status = APPLET_FAIL; goto exit; } TRACE_INFO("GPNVM achieved\n\r"); pMailbox->status = APPLET_SUCCESS; } #endif // #if !defined (at91sam7a3) // ---------------------------------------------------------- // SET SECURITY : // ---------------------------------------------------------- #if defined(CHIP_FLASH_EFC) && !defined (at91sam7a3) else if (pMailbox->command == APPLET_CMD_SECURITY) { TRACE_INFO("SET SECURITY BIT command \n\r"); if (FLASHD_SetSecurityBit() != 0) { TRACE_INFO("SET SECURITY BIT failed! \n\r"); pMailbox->status = APPLET_FAIL; goto exit; } TRACE_INFO("SET SECURITY BIT achieved\n\r"); pMailbox->status = APPLET_SUCCESS; } #endif #if defined(at91sam3u4) // ---------------------------------------------------------- // READ UNIQUE ID : // ---------------------------------------------------------- else if (pMailbox->command == APPLET_CMD_READ_UNIQUE_ID) { TRACE_INFO("READ UNIQUE ID command \n\r"); if (FLASHD_ReadUniqueID (pMailbox->argument.inputReadUniqueID.bufferAddr) != 0) { TRACE_INFO("Read Unique ID failed! \n\r"); pMailbox->status = APPLET_FAIL; goto exit; } TRACE_INFO("Read Unique ID achieved\n\r"); pMailbox->status = APPLET_SUCCESS; } #endif exit: // Acknowledge the end of command TRACE_INFO("\tEnd of Applet %x %x.\n\r", pMailbox->command, pMailbox->status); // Notify the host application of the end of the command processing pMailbox->command = ~(pMailbox->command); // Send ACK character if (comType == DBGU_COM_TYPE) { DBGU_PutChar(0x6); } return 0; }