/** * @brief Erase the specified FLASH memory sector * @param Sector FLASH sector to erase * @param Banks Banks to be erased * This parameter can be one of the following values: * @arg FLASH_BANK_1: Bank1 to be erased * @arg FLASH_BANK_2: Bank2 to be erased * @arg FLASH_BANK_BOTH: Bank1 and Bank2 to be erased * @param VoltageRange The device program/erase parallelism. * This parameter can be one of the following values: * @arg FLASH_VOLTAGE_RANGE_1 : Flash program/erase by 8 bits * @arg FLASH_VOLTAGE_RANGE_2 : Flash program/erase by 16 bits * @arg FLASH_VOLTAGE_RANGE_3 : Flash program/erase by 32 bits * @arg FLASH_VOLTAGE_RANGE_4 : Flash program/erase by 62 bits * * @retval None */ void FLASH_Erase_Sector(uint32_t Sector, uint32_t Banks, uint32_t VoltageRange) { assert_param(IS_FLASH_BANK_EXCLUSIVE(Banks)); assert_param(IS_VOLTAGERANGE(VoltageRange)); assert_param(IS_FLASH_SECTOR(Sector)); if((Banks & FLASH_BANK_1) == FLASH_BANK_1) { /* reset Program/erase VoltageRange for Bank1 */ FLASH->CR1 &= ~(FLASH_CR_PSIZE | FLASH_CR_SNB); FLASH->CR1 |= (FLASH_CR_SER | VoltageRange | (Sector << POSITION_VAL(FLASH_CR_SNB))); FLASH->CR1 |= FLASH_CR_START; } if((Banks & FLASH_BANK_2) == FLASH_BANK_2) { /* reset Program/erase VoltageRange for Bank2 */ FLASH->CR2 &= ~(FLASH_CR_PSIZE | FLASH_CR_SNB); FLASH->CR2 |= (FLASH_CR_SER | VoltageRange | (Sector << POSITION_VAL(FLASH_CR_SNB))); FLASH->CR2 |= FLASH_CR_START; } }
/** * @brief Erase the specified FLASH memory sector * @param Sector: FLASH sector to erase * The value of this parameter depend on device used within the same series * @param VoltageRange: The device voltage range which defines the erase parallelism. * This parameter can be one of the following values: * @arg FLASH_VOLTAGE_RANGE_1: when the device voltage range is 1.8V to 2.1V, * the operation will be done by byte (8-bit) * @arg FLASH_VOLTAGE_RANGE_2: when the device voltage range is 2.1V to 2.7V, * the operation will be done by half word (16-bit) * @arg FLASH_VOLTAGE_RANGE_3: when the device voltage range is 2.7V to 3.6V, * the operation will be done by word (32-bit) * @arg FLASH_VOLTAGE_RANGE_4: when the device voltage range is 2.7V to 3.6V + External Vpp, * the operation will be done by double word (64-bit) * * @retval None */ void FLASH_Erase_Sector(uint32_t Sector, uint8_t VoltageRange) { uint32_t tmp_psize = 0; /* Check the parameters */ assert_param(IS_FLASH_SECTOR(Sector)); assert_param(IS_VOLTAGERANGE(VoltageRange)); if(VoltageRange == FLASH_VOLTAGE_RANGE_1) { tmp_psize = FLASH_PSIZE_BYTE; } else if(VoltageRange == FLASH_VOLTAGE_RANGE_2) { tmp_psize = FLASH_PSIZE_HALF_WORD; } else if(VoltageRange == FLASH_VOLTAGE_RANGE_3) { tmp_psize = FLASH_PSIZE_WORD; } else { tmp_psize = FLASH_PSIZE_DOUBLE_WORD; } /* If the previous operation is completed, proceed to erase the sector */ CLEAR_BIT(FLASH->CR, FLASH_CR_PSIZE); FLASH->CR |= tmp_psize; CLEAR_BIT(FLASH->CR, FLASH_CR_SNB); FLASH->CR |= FLASH_CR_SER | (Sector << POSITION_VAL(FLASH_CR_SNB)); FLASH->CR |= FLASH_CR_STRT; }
/** * @brief Erases a specified FLASH Sector. * * @param FLASH_Sector: The Sector number to be erased. * This parameter can be a value between FLASH_Sector_0 and FLASH_Sector_11 * * @param VoltageRange: The device voltage range which defines the erase parallelism. * This parameter can be one of the following values: * @arg VoltageRange_1: when the device voltage range is 1.8V to 2.1V, * the operation will be done by byte (8-bit) * @arg VoltageRange_2: when the device voltage range is 2.1V to 2.7V, * the operation will be done by half word (16-bit) * @arg VoltageRange_3: when the device voltage range is 2.7V to 3.6V, * the operation will be done by word (32-bit) * @arg VoltageRange_4: when the device voltage range is 2.7V to 3.6V + External Vpp, * the operation will be done by double word (64-bit) * * @retval FLASH Status: The returned value can be: FLASH_BUSY, FLASH_ERROR_PROGRAM, * FLASH_ERROR_WRP, FLASH_ERROR_OPERATION or FLASH_COMPLETE. */ FLASH_Status FLASH_EraseSector(uint32_t FLASH_Sector, uint8_t VoltageRange) { uint32_t tmp_psize = 0x0; FLASH_Status status = FLASH_COMPLETE; /* Check the parameters */ assert_param(IS_FLASH_SECTOR(FLASH_Sector)); assert_param(IS_VOLTAGERANGE(VoltageRange)); if(VoltageRange == VoltageRange_1) { tmp_psize = FLASH_PSIZE_BYTE; } else if(VoltageRange == VoltageRange_2) { tmp_psize = FLASH_PSIZE_HALF_WORD; } else if(VoltageRange == VoltageRange_3) { tmp_psize = FLASH_PSIZE_WORD; } else { tmp_psize = FLASH_PSIZE_DOUBLE_WORD; } /* Wait for last operation to be completed */ status = FLASH_WaitForLastOperation(); if(status == FLASH_COMPLETE) { /* if the previous operation is completed, proceed to erase the sector */ FLASH->CR &= CR_PSIZE_MASK; FLASH->CR |= tmp_psize; FLASH->CR &= SECTOR_MASK; FLASH->CR |= FLASH_CR_SER | FLASH_Sector; FLASH->CR |= FLASH_CR_STRT; /* Wait for last operation to be completed */ status = FLASH_WaitForLastOperation(); /* if the erase operation is completed, disable the SER Bit */ FLASH->CR &= (~FLASH_CR_SER); FLASH->CR &= SECTOR_MASK; } /* Return the Erase Status */ return status; }
/** * @brief Erase the specified FLASH memory sector * @param Sector: FLASH sector to erase * The value of this parameter depend on device used within the same series * @param VoltageRange: The device voltage range which defines the erase parallelism. * This parameter can be one of the following values: * @arg FLASH_VOLTAGE_RANGE_1: when the device voltage range is 1.8V to 2.1V, * the operation will be done by byte (8-bit) * @arg FLASH_VOLTAGE_RANGE_2: when the device voltage range is 2.1V to 2.7V, * the operation will be done by half word (16-bit) * @arg FLASH_VOLTAGE_RANGE_3: when the device voltage range is 2.7V to 3.6V, * the operation will be done by word (32-bit) * @arg FLASH_VOLTAGE_RANGE_4: when the device voltage range is 2.7V to 3.6V + External Vpp, * the operation will be done by double word (64-bit) * * @retval None */ void FLASH_Erase_Sector(uint32_t Sector, uint8_t VoltageRange) { uint32_t tmp_psize = 0; /* Check the parameters */ assert_param(IS_FLASH_SECTOR(Sector)); assert_param(IS_VOLTAGERANGE(VoltageRange)); if(VoltageRange == FLASH_VOLTAGE_RANGE_1) { tmp_psize = FLASH_PSIZE_BYTE; } else if(VoltageRange == FLASH_VOLTAGE_RANGE_2) { tmp_psize = FLASH_PSIZE_HALF_WORD; } else if(VoltageRange == FLASH_VOLTAGE_RANGE_3) { tmp_psize = FLASH_PSIZE_WORD; } else { tmp_psize = FLASH_PSIZE_DOUBLE_WORD; } /* Need to add offset of 4 when sector higher than FLASH_SECTOR_11 */ if(Sector > FLASH_SECTOR_11) { Sector += 4; } /* If the previous operation is completed, proceed to erase the sector */ FLASH->CR &= CR_PSIZE_MASK; FLASH->CR |= tmp_psize; FLASH->CR &= SECTOR_MASK; FLASH->CR |= FLASH_CR_SER | (Sector << POSITION_VAL(FLASH_CR_SNB)); FLASH->CR |= FLASH_CR_STRT; }
void updateProgram(void) { int clear = 0; int cmdByte, i, temp; FLASH_EraseResult result; uint32_t addr, maxAddr = 0; uint16_t endSector = 0xFFFF; _ee_getReserved(_AI_EE_RES_ADDR_MAX_SECTOR, &endSector); if (endSector > APPLICATION_END_SECTOR || !IS_FLASH_SECTOR(endSector)) endSector = APPLICATION_END_SECTOR; lcd_clear(); lcd_printf("Aithon Board\nProgramming..."); // Unlock the Flash Program Erase controller FLASH_If_Init(); while (TRUE) { led_toggle(0); cmdByte = getByte(); debugPrintCmd(cmdByte); switch (cmdByte) { case SYNC: // sync flushInterface(); sendResponse(SYNC, ACK); break; case ERASE_FLASH_START: if (FLASH_If_Erase_Start() == FLASH_ERASE_IN_PROGRESS) sendResponse(ERASE_FLASH_START, ACK); else sendResponse(ERASE_FLASH_START, NACK); break; case ERASE_FLASH_STATUS: result = FLASH_If_Erase_Status(endSector); if (result == FLASH_ERASE_COMPLETE) sendResponse(ERASE_FLASH_STATUS, ACK); else if (result == FLASH_ERASE_IN_PROGRESS) sendResponse(ERASE_FLASH_STATUS, BUSY); else sendResponse(ERASE_FLASH_STATUS, NACK); break; case SET_ADDR: // Read in the address, MSB first. addr = 0; for (i = 0; i < 4; i++) { if ((temp = getByte()) == Q_TIMEOUT) break; addr |= (((uint8_t) temp) & 0xFF) << (i * 8); } // Check for errors. if (temp == Q_TIMEOUT) sendResponse(SET_ADDR, NACK); else { sendResponse(SET_ADDR, ACK); // We'll get relative addresses, so add the start address. addr += APPLICATION_START_ADDRESS; } break; case CHECK_ADDR: // Get the checksum temp = getByte(); if (temp == Q_TIMEOUT) sendResponse(CHECK_ADDR, NACK); else { // Subtract the start address before calculating the checksum addr -= APPLICATION_START_ADDRESS; if (temp == calcChecksum((uint8_t *)&addr, 4)) sendResponse(CHECK_ADDR, ACK); else sendResponse(CHECK_ADDR, NACK); addr += APPLICATION_START_ADDRESS; } break; case FILL_BUFFER: for (i = 0; i < PACKET_LEN; i++) { if ((temp = getByte()) == Q_TIMEOUT) break; _buffer[i] = (uint8_t) (temp & 0xFF); } if (temp == Q_TIMEOUT) sendResponse(FILL_BUFFER, NACK); else sendResponse(FILL_BUFFER, ACK); break; case CHECK_BUFFER: // Get the checksum temp = getByte(); if (temp != Q_TIMEOUT && temp == calcChecksum(_buffer, PACKET_LEN)) sendResponse(CHECK_BUFFER, ACK); else sendResponse(CHECK_BUFFER, NACK); break; case COMMIT_BUFFER: maxAddr = addr + PACKET_LEN - 1; if (FLASH_If_Write((__IO uint32_t *)&addr, (uint32_t *)_buffer, PACKET_LEN/4)) sendResponse(COMMIT_BUFFER, NACK); else sendResponse(COMMIT_BUFFER, ACK); break; case START_PROGRAM: sendResponse(START_PROGRAM, ACK); flushInterface(); _ee_putReserved(_AI_EE_RES_ADDR_MAX_SECTOR, FLASH_Addr_To_Sector(maxAddr)); delayS(1); startProgram(); // ...should never get here return; case Q_TIMEOUT: default: if (clear == 0) { lcd_clear(); clear = 1; } lcd_printf ("0%x ", cmdByte); break; } } }