/** *@brief Programs a memory block * @param[in] MemType The type of memory to program * @param[in] BlockNum The block number * @param[in] ProgMode The programming mode. * @param[in] Buffer The buffer address of source data. * @retval * None. * @par Required preconditions: * The FLASH_ProgramBlock function should be executed from RAM. * PointerAttr define is declared in the stm8s.h file to select if pointer will be declared * as near (2 bytes) or far (3 bytes). */ void FLASH_ProgramBlock(u16 BlockNum, FLASH_MemType_TypeDef MemType, FLASH_ProgramMode_TypeDef ProgMode, u8 *Buffer) { u16 Count = 0; u32 StartAddress = 0; u16 timeout = OPERATION_TIMEOUT; /* Check parameters */ assert_param(IS_MEMORY_TYPE_OK(MemType)); assert_param(IS_FLASH_PROGRAM_MODE_OK(ProgMode)); if (MemType == FLASH_MEMTYPE_PROG) { assert_param(IS_FLASH_PROG_BLOCK_NUMBER_OK(BlockNum)); StartAddress = FLASH_PROG_START_PHYSICAL_ADDRESS; } else { assert_param(IS_FLASH_DATA_BLOCK_NUMBER_OK(BlockNum)); StartAddress = FLASH_DATA_START_PHYSICAL_ADDRESS; } /* Point to the first block address */ StartAddress = StartAddress + ((u32)BlockNum * FLASH_BLOCK_SIZE); /* Selection of Standard or Fast programming mode */ if (ProgMode == FLASH_PROGRAMMODE_STANDARD) { /* Standard programming mode */ /*No need in standard mode */ FLASH->CR2 |= FLASH_CR2_PRG; FLASH->NCR2 &= (u8)(~FLASH_NCR2_NPRG); } else { /* Fast programming mode */ FLASH->CR2 |= FLASH_CR2_FPRG; FLASH->NCR2 &= (u8)(~FLASH_NCR2_NFPRG); } /* Copy data bytes from RAM to FLASH memory */ for (Count = 0; Count < FLASH_BLOCK_SIZE; Count++) { *((PointerAttr u8*)StartAddress + Count) = ((u8)(Buffer[Count])); } #if defined (STM8S208) || defined(STM8S207) || defined(STM8S105) if (MemType == FLASH_MEMTYPE_DATA) { /* Waiting until High voltage flag is cleared*/ while ((FLASH->IAPSR & FLASH_IAPSR_HVOFF) != 0x00 || (timeout == 0x00)) { timeout--; } } #endif /* STM8S208, STM8S207, STM8S105 */ }
/** * @brief Programs a memory block * @note This function should be called and executed from RAM. * @param FLASH_MemType : The type of memory to program * @param BlockNum : The block number * @param FLASH_ProgMode : The programming mode. * @param Buffer : Pointer to buffer containing source data. * @retval None. */ IN_RAM(void FLASH_ProgramBlock(uint16_t BlockNum, FLASH_MemType_TypeDef FLASH_MemType, FLASH_ProgramMode_TypeDef FLASH_ProgMode, uint8_t *Buffer)) { uint16_t Count = 0; uint32_t startaddress = 0; /* Check parameters */ assert_param(IS_MEMORY_TYPE_OK(FLASH_MemType)); assert_param(IS_FLASH_PROGRAM_MODE_OK(FLASH_ProgMode)); if (FLASH_MemType == FLASH_MEMTYPE_PROG) { assert_param(IS_FLASH_PROG_BLOCK_NUMBER_OK(BlockNum)); startaddress = FLASH_PROG_START_PHYSICAL_ADDRESS; } else { assert_param(IS_FLASH_DATA_BLOCK_NUMBER_OK(BlockNum)); startaddress = FLASH_DATA_START_PHYSICAL_ADDRESS; } /* Point to the first block address */ startaddress = startaddress + ((uint32_t)BlockNum * FLASH_BLOCK_SIZE); /* Selection of Standard or Fast programming mode */ if (FLASH_ProgMode == FLASH_PROGRAMMODE_STANDARD) { /* Standard programming mode */ /*No need in standard mode */ FLASH->CR2 |= FLASH_CR2_PRG; FLASH->NCR2 &= (uint8_t)(~FLASH_NCR2_NPRG); } else { /* Fast programming mode */ FLASH->CR2 |= FLASH_CR2_FPRG; FLASH->NCR2 &= (uint8_t)(~FLASH_NCR2_NFPRG); } /* Copy data bytes from RAM to FLASH memory */ for (Count = 0; Count < FLASH_BLOCK_SIZE; Count++) { #if defined (STM8S208) || defined(STM8S207) || defined(STM8S007) || defined(STM8S105) || \ defined(STM8S005) || defined (STM8AF62Ax) || defined (STM8AF52Ax) || defined (STM8AF626x) *((PointerAttr uint8_t*) (uint16_t)startaddress + Count) = ((uint8_t)(Buffer[Count])); #elif defined(STM8S103) || defined(STM8S003) || defined (STM8S903) *((PointerAttr uint8_t*) (uint16_t)startaddress + Count) = ((uint8_t)(Buffer[Count])); #endif } }
/** * @brief Programs a memory block * @note This function should be executed from RAM. * @param FLASH_MemType : The type of memory to program * @param BlockNum : The block number * @param FLASH_ProgMode : The programming mode. * @param Buffer : Pointer to buffer containing source data. * @retval None. */ IN_RAM(void FLASH_ProgramBlock(uint16_t BlockNum, FLASH_MemType_TypeDef FLASH_MemType, FLASH_ProgramMode_TypeDef FLASH_ProgMode, uint8_t *Buffer)) { uint16_t Count = 0; uint32_t startaddress = 0; /* Check parameters */ assert_param(IS_MEMORY_TYPE_OK(FLASH_MemType)); assert_param(IS_FLASH_PROGRAM_MODE_OK(FLASH_ProgMode)); if(FLASH_MemType == FLASH_MEMTYPE_PROG) { assert_param(IS_FLASH_PROG_BLOCK_NUMBER_OK(BlockNum)); startaddress = FLASH_PROG_START_PHYSICAL_ADDRESS; } else { assert_param(IS_FLASH_DATA_BLOCK_NUMBER_OK(BlockNum)); startaddress = FLASH_DATA_START_PHYSICAL_ADDRESS; } /* Point to the first block address */ startaddress = startaddress + ((uint32_t)BlockNum * FLASH_BLOCK_SIZE); /* Selection of Standard or Fast programming mode */ if(FLASH_ProgMode == FLASH_PROGRAMMODE_STANDARD) { /* Standard programming mode */ /*No need in standard mode */ FLASH->CR2 |= FLASH_CR2_PRG; FLASH->NCR2 &= (uint8_t)(~FLASH_NCR2_NPRG); } else { /* Fast programming mode */ FLASH->CR2 |= FLASH_CR2_FPRG; FLASH->NCR2 &= (uint8_t)(~FLASH_NCR2_NFPRG); } /* Copy data bytes from RAM to FLASH memory */ for(Count = 0; Count < FLASH_BLOCK_SIZE; Count++) { #ifndef _SDCC_ *((PointerAttr uint8_t*) (MemoryAddressCast)startaddress + Count) = ((uint8_t)(Buffer[Count])); #else write_byte_address(startaddress + Count, ((uint8_t)(Buffer[Count]))); // SDCC patch: required for far pointers #endif // _SDCC_ } }