From 1620b54e1cfcc97426e403405a470d060061afd8 Mon Sep 17 00:00:00 2001 From: Dimitris Mantzouranis Date: Fri, 17 Nov 2023 11:58:41 +0200 Subject: [PATCH] sn32: implement EFL LLD for flash access --- os/hal/ports/SN32/LLD/SN32F2xx/FLASH/Flash.c | 140 ------ os/hal/ports/SN32/LLD/SN32F2xx/FLASH/Flash.h | 48 -- .../ports/SN32/LLD/SN32F2xx/FLASH/driver.mk | 3 - os/hal/ports/SN32/SN32F240/hal_efl_lld.c | 462 ++++++++++++++++++ os/hal/ports/SN32/SN32F240/hal_efl_lld.h | 129 +++++ os/hal/ports/SN32/SN32F240/platform.mk | 3 +- os/hal/ports/SN32/SN32F240/sn32_registry.h | 10 + os/hal/ports/SN32/SN32F240B/hal_efl_lld.c | 462 ++++++++++++++++++ os/hal/ports/SN32/SN32F240B/hal_efl_lld.h | 129 +++++ os/hal/ports/SN32/SN32F240B/platform.mk | 4 +- os/hal/ports/SN32/SN32F240B/sn32_registry.h | 10 + os/hal/ports/SN32/SN32F260/hal_efl_lld.c | 462 ++++++++++++++++++ os/hal/ports/SN32/SN32F260/hal_efl_lld.h | 129 +++++ os/hal/ports/SN32/SN32F260/platform.mk | 4 +- os/hal/ports/SN32/SN32F260/sn32_registry.h | 10 + 15 files changed, 1809 insertions(+), 196 deletions(-) delete mode 100644 os/hal/ports/SN32/LLD/SN32F2xx/FLASH/Flash.c delete mode 100644 os/hal/ports/SN32/LLD/SN32F2xx/FLASH/Flash.h delete mode 100644 os/hal/ports/SN32/LLD/SN32F2xx/FLASH/driver.mk create mode 100644 os/hal/ports/SN32/SN32F240/hal_efl_lld.c create mode 100644 os/hal/ports/SN32/SN32F240/hal_efl_lld.h create mode 100644 os/hal/ports/SN32/SN32F240B/hal_efl_lld.c create mode 100644 os/hal/ports/SN32/SN32F240B/hal_efl_lld.h create mode 100644 os/hal/ports/SN32/SN32F260/hal_efl_lld.c create mode 100644 os/hal/ports/SN32/SN32F260/hal_efl_lld.h diff --git a/os/hal/ports/SN32/LLD/SN32F2xx/FLASH/Flash.c b/os/hal/ports/SN32/LLD/SN32F2xx/FLASH/Flash.c deleted file mode 100644 index f573bf7a91..0000000000 --- a/os/hal/ports/SN32/LLD/SN32F2xx/FLASH/Flash.c +++ /dev/null @@ -1,140 +0,0 @@ -/******************** (C) COPYRIGHT 2017 SONiX ******************************* -* COMPANY: SONiX -* DATE: 2017/07 -* AUTHOR: SA1 -* IC: SN32F240B -* DESCRIPTION: Flash related functions. -*____________________________________________________________________________ -* REVISION Date User Description -* 1.0 2017/07/07 SA1 First release -* -*____________________________________________________________________________ -* THE PRESENT SOFTWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS -* WITH CODING INFORMATION REGARDING THEIR PRODUCTS TIME TO MARKET. -* SONiX SHALL NOT BE HELD LIABLE FOR ANY DIRECT, INDIRECT OR CONSEQUENTIAL -* DAMAGES WITH RESPECT TO ANY CLAIMS ARISING FROM THE CONTENT OF SUCH SOFTWARE -* AND/OR THE USE MADE BY CUSTOMERS OF THE CODING INFORMATION CONTAINED HEREIN -* IN CONNECTION WITH THEIR PRODUCTS. -*****************************************************************************/ - -/*_____ I N C L U D E S ____________________________________________________*/ -#include "Flash.h" - -/*_____ D E C L A R A T I O N S ____________________________________________*/ - -/*_____ D E F I N I T I O N S ______________________________________________*/ -#define SN32_JUMPLOADER_SIZE 0x200 - -/*_____ M A C R O S ________________________________________________________*/ - - -/*_____ F U N C T I O N S __________________________________________________*/ -/***************************************************************************** -* Function : FLASH_EraseSector -* Description : Erase assigned sector address in Flash ROM -* Input : adr - Sector start address -* Output : None -* Return : None -* Note : None -*****************************************************************************/ -FLASH_Status FLASH_EraseSector (uint32_t adr) -{ - // never touch the jumploader - if (adr < SN32_JUMPLOADER_SIZE) return FLASH_FAIL; - - SN_FLASH->CTRL = FLASH_PER; // Page Erase Enabled - SN_FLASH->ADDR = adr; // Page Address - - FLASH_WAIT_FOR_DONE - - SN_FLASH->CTRL |= FLASH_START; // Start Erase - - FLASH_WAIT_FOR_DONE - - return (FLASH_OKAY); -} - - -/***************************************************************************** -* Function : Flash_ProgramPage -* Description : Program assigned page in Flash ROM -* Input : adr - Page start address (word-alignment) of Flash -* sz - Content size to be programmed (Bytes) -* Data - the Source data -* Output : None -* Return : FLASH_OKAY or FLASH_FAIL -* Note : None -*****************************************************************************/ -FLASH_Status FLASH_ProgramPage (uint32_t adr, uint32_t sz, uint32_t Data) -{ - // never touch the jumploader - if (adr < SN32_JUMPLOADER_SIZE) return FLASH_FAIL; - - SN_FLASH->CTRL = FLASH_PG; // Programming Enabled - SN_FLASH->ADDR = adr; - - FLASH_WAIT_FOR_DONE - - *(uint32_t*)adr = Data; - - while (sz) { - - SN_FLASH->DATA = Data; - - FLASH_WAIT_FOR_DONE - - // Go to next Word - adr += 4; - sz -= 4; - } - - // Check for Errors - if ((SN_FLASH->STATUS & FLASH_ERR) == FLASH_ERR) { - SN_FLASH->STATUS = 0; - return (FLASH_FAIL); - } - - SN_FLASH->CTRL |= FLASH_START; // Start Program - - FLASH_WAIT_FOR_DONE - - // Check for Errors - if ((SN_FLASH->STATUS & FLASH_ERR) == FLASH_ERR) { - SN_FLASH->STATUS = 0; - return (FLASH_FAIL); - } - - return (FLASH_OKAY); -} - -/***************************************************************************** -* Function : FLASH_ProgramWord -* Description : Program a word at a specified address -* Input : adr - Page start address (word-alignment) of Flash -* Data - the Source data -* Output : None -* Return : FLASH_OKAY or FLASH_ERR -* Note : None -*****************************************************************************/ -FLASH_Status FLASH_ProgramDWord(uint32_t adr, uint32_t Data) { - FLASH_Status status = FLASH_ProgramPage(adr, 4, Data); - - return status; -} - -/***************************************************************************** -* Function : FLASH_Checksum -* Description : Calculate Checksum in Flash ROM -* Input : None -* Output : Checksum of User ROM -* Return : None -* Note : None -*****************************************************************************/ -uint16_t FLASH_Checksum (void) -{ - SN_FLASH->CTRL = FLASH_CHK; - - FLASH_WAIT_FOR_DONE - - return (uint16_t) (SN_FLASH->CHKSUM); -} diff --git a/os/hal/ports/SN32/LLD/SN32F2xx/FLASH/Flash.h b/os/hal/ports/SN32/LLD/SN32F2xx/FLASH/Flash.h deleted file mode 100644 index 2a2973dd72..0000000000 --- a/os/hal/ports/SN32/LLD/SN32F2xx/FLASH/Flash.h +++ /dev/null @@ -1,48 +0,0 @@ -#ifndef __SN32F2XX_FLASH_H -#define __SN32F2XX_FLASH_H - -/*_____ I N C L U D E S ____________________________________________________*/ -#include -#include - - -/*_____ D E F I N I T I O N S ______________________________________________*/ -//FLASH HW -#define FLASH_PAGE_SIZE 64 -#define FLASH_F240B_MAX_ROM_SIZE 0xFFFF - - -// Flash Control Register definitions -#define FLASH_PG 0x00000001 -#define FLASH_PER 0x00000002 -#define FLASH_MER 0x00000004 -#define FLASH_START 0x00000040 -#define FLASH_CHK 0x00000080 - -// Flash Status Register definitions -#define FLASH_BUSY 0x00000001 -#define FLASH_ERR 0x00000004 - -#define FLASH_WAIT_FOR_DONE while (SN_FLASH->STATUS & FLASH_BUSY) {__asm__("NOP");} - - -/*_____ M A C R O S ________________________________________________________*/ - -//Flash Low Power Mode -#define __FLASH_LPM_DISABLE SN_FLASH->LPCTRL = 0x5AFA0000; //HCLK<=12MHz -#define __FLASH_LPM_MEDIUM_MODE SN_FLASH->LPCTRL = 0x5AFA0003; //12MHzLPCTRL = 0x5AFA0004;SN_FLASH->LPCTRL = 0x5AFA0005;SN_FLASH->LPCTRL = 0x5AFA000D; //HCLK>24MHz - -//Flash Status -#define __FLASH_CLEAR_ERROR_STATUS SN_FLASH->STATUS &= ~FLASH_PGERR - -/*_____ D E C L A R A T I O N S ____________________________________________*/ -typedef enum { FLASH_FAIL, FLASH_OKAY} FLASH_Status; - -void FLASH_MassErase (void); -FLASH_Status FLASH_EraseSector (uint32_t); -FLASH_Status FLASH_ProgramPage (uint32_t, uint32_t, uint32_t); -FLASH_Status FLASH_ProgramDWord(uint32_t, uint32_t); -uint16_t FLASH_Checksum(void); - -#endif /* __SN32F2XX_FLASH_H */ diff --git a/os/hal/ports/SN32/LLD/SN32F2xx/FLASH/driver.mk b/os/hal/ports/SN32/LLD/SN32F2xx/FLASH/driver.mk deleted file mode 100644 index 16061a8303..0000000000 --- a/os/hal/ports/SN32/LLD/SN32F2xx/FLASH/driver.mk +++ /dev/null @@ -1,3 +0,0 @@ -PLATFORMSRC += $(CHIBIOS_CONTRIB)/os/hal/ports/SN32/LLD/SN32F2xx/FLASH/Flash.c - -PLATFORMINC += $(CHIBIOS_CONTRIB)/os/hal/ports/SN32/LLD/SN32F2xx/FLASH \ No newline at end of file diff --git a/os/hal/ports/SN32/SN32F240/hal_efl_lld.c b/os/hal/ports/SN32/SN32F240/hal_efl_lld.c new file mode 100644 index 0000000000..b6ef39fe50 --- /dev/null +++ b/os/hal/ports/SN32/SN32F240/hal_efl_lld.c @@ -0,0 +1,462 @@ +/* + ChibiOS - Copyright (C) 2006..2023 Giovanni Di Sirio + Copyright (C) 2023 Dimitris Mantzouranis + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +*/ + +/** + * @file hal_efl_lld.c + * @brief SN32F24xB Embedded Flash subsystem low level driver source. + * + * @addtogroup HAL_EFL + * @{ + */ + +#include + +#include "hal.h" + +#if (HAL_USE_EFL == TRUE) || defined(__DOXYGEN__) + +/*===========================================================================*/ +/* Driver local definitions. */ +/*===========================================================================*/ + +#define SN32_FLASH_LINE_MASK (SN32_FLASH_LINE_SIZE - 1U) + +/*===========================================================================*/ +/* Driver exported variables. */ +/*===========================================================================*/ + +/** + * @brief EFL1 driver identifier. + */ +EFlashDriver EFLD1; + +/*===========================================================================*/ +/* Driver local variables and types. */ +/*===========================================================================*/ + +static const flash_descriptor_t efl_lld_descriptor = { + .attributes = FLASH_ATTR_MEMORY_MAPPED, + .page_size = SN32_FLASH_LINE_SIZE, + .sectors_count = SN32_FLASH_NUMBER_OF_BANKS * + SN32_FLASH_SECTORS_PER_BANK, + .sectors = NULL, + .sectors_size = SN32_FLASH_SECTOR_SIZE, + .address = (uint8_t *)SN32_FLASH_BASE, + .size = SN32_FLASH_NUMBER_OF_BANKS * + SN32_FLASH_SECTORS_PER_BANK * + SN32_FLASH_SECTOR_SIZE +}; + +/*===========================================================================*/ +/* Driver local functions. */ +/*===========================================================================*/ + +static inline void sn32_flash_enable_pgm(EFlashDriver *eflp) { + + eflp->flash->CTRL = SN32_FLASH_CTRL_PG; +} + +static inline void sn32_flash_start_pgm(EFlashDriver *eflp) { + + eflp->flash->CTRL |= SN32_FLASH_CTRL_START; +} + +static inline void sn32_flash_clear_status(EFlashDriver *eflp) { + + /* Clearing error conditions.*/ + eflp->flash->STATUS_b.ERR = 0; +} + +static inline void sn32_flash_wait_busy(EFlashDriver *eflp) { + + /* Wait for busy bit clear.*/ + while ((eflp->flash->STATUS & SN32_FLASH_STATUS_BUSY) != 0U) { + } +} + +static inline flash_error_t sn32_flash_check_errors(EFlashDriver *eflp) { + uint32_t error = eflp->flash->STATUS_b.ERR; + + /* Clearing error conditions.*/ + eflp->flash->STATUS_b.ERR = 0; + + /* Decoding relevant errors.*/ + if ((error) != 0U) { + return FLASH_ERROR_HW_FAILURE; + } + + return FLASH_NO_ERROR; +} + +/*===========================================================================*/ +/* Driver interrupt handlers. */ +/*===========================================================================*/ + +/*===========================================================================*/ +/* Driver exported functions. */ +/*===========================================================================*/ + +/** + * @brief Low level Embedded Flash driver initialization. + * + * @notapi + */ +void efl_lld_init(void) { + + /* Driver initialization.*/ + eflObjectInit(&EFLD1); + EFLD1.flash = SN_FLASH; +} + +/** + * @brief Configures and activates the Embedded Flash peripheral. + * + * @param[in] eflp pointer to a @p EFlashDriver structure + * + * @notapi + */ +void efl_lld_start(EFlashDriver *eflp) { + eflp->flash->CTRL = 0x00000000U; +} + +/** + * @brief Deactivates the Embedded Flash peripheral. + * + * @param[in] eflp pointer to a @p EFlashDriver structure + * + * @notapi + */ +void efl_lld_stop(EFlashDriver *eflp) { + +} + +/** + * @brief Gets the flash descriptor structure. + * + * @param[in] ip pointer to a @p EFlashDriver instance + * @return A flash device descriptor. + * @retval Pointer to single bank if DBM not enabled. + * @retval Pointer to bank1 if DBM enabled. + * + * @notapi + */ +const flash_descriptor_t *efl_lld_get_descriptor(void *instance) { + + (void)instance; + + return &efl_lld_descriptor; +} + +/** + * @brief Read operation. + * + * @param[in] ip pointer to a @p EFlashDriver instance + * @param[in] offset offset within full flash address space + * @param[in] n number of bytes to be read + * @param[out] rp pointer to the data buffer + * @return An error code. + * @retval FLASH_NO_ERROR if there is no erase operation in progress. + * @retval FLASH_BUSY_ERASING if there is an erase operation in progress. + * @retval FLASH_ERROR_READ if the read operation failed. + * @retval FLASH_ERROR_HW_FAILURE if access to the memory failed. + * + * @notapi + */ +flash_error_t efl_lld_read(void *instance, flash_offset_t offset, + size_t n, uint8_t *rp) { + EFlashDriver *devp = (EFlashDriver *)instance; + flash_error_t err = FLASH_NO_ERROR; + + osalDbgCheck((instance != NULL) && (rp != NULL) && (n > 0U)); + osalDbgCheck((size_t)offset + n <= (size_t)efl_lld_descriptor.size); + osalDbgAssert((devp->state == FLASH_READY) || (devp->state == FLASH_ERASE), + "invalid state"); + + /* No reading while erasing.*/ + if (devp->state == FLASH_ERASE) { + return FLASH_BUSY_ERASING; + } + + /* FLASH_READ state while the operation is performed.*/ + devp->state = FLASH_READ; + + /* Clearing error status bits.*/ + sn32_flash_clear_status(devp); + + /* Actual read implementation.*/ + memcpy((void *)rp, (const void *)efl_lld_descriptor.address + offset, n); + + /* Ready state again.*/ + devp->state = FLASH_READY; + + return err; +} + +/** + * @brief Program operation. + * @note The device supports ECC, it is only possible to write erased + * pages once except when writing all zeroes. + * + * @param[in] ip pointer to a @p EFlashDriver instance + * @param[in] offset offset within full flash address space + * @param[in] n number of bytes to be programmed + * @param[in] pp pointer to the data buffer + * @return An error code. + * @retval FLASH_NO_ERROR if there is no erase operation in progress. + * @retval FLASH_BUSY_ERASING if there is an erase operation in progress. + * @retval FLASH_ERROR_PROGRAM if the program operation failed. + * @retval FLASH_ERROR_HW_FAILURE if access to the memory failed. + * + * @notapi + */ + +flash_error_t efl_lld_program(void *instance, flash_offset_t offset, + size_t n, const uint8_t *pp) { + EFlashDriver *devp = (EFlashDriver *)instance; + flash_error_t err = FLASH_NO_ERROR; + volatile uint32_t *address; + + osalDbgCheck((instance != NULL) && (pp != NULL) && (n > 0U)); + osalDbgCheck((size_t)offset + n <= (size_t)efl_lld_descriptor.size); + osalDbgAssert((devp->state == FLASH_READY) || (devp->state == FLASH_ERASE), + "invalid state"); + + /* No programming while erasing.*/ + if (devp->state == FLASH_ERASE) { + return FLASH_BUSY_ERASING; + } + + /* FLASH_PGM state while the operation is performed.*/ + devp->state = FLASH_PGM; + + /* Clearing error status bits.*/ + sn32_flash_clear_status(devp); + + /* Enabling PGM mode in the controller.*/ + sn32_flash_enable_pgm(devp); + + /* Calculate the address from the offset. */ + address = (volatile uint32_t *)(efl_lld_descriptor.address + + (offset & ~SN32_FLASH_LINE_MASK)); + + if (address < (volatile uint32_t *)SN32_JUMPLOADER_SIZE) { + return FLASH_ERROR_HW_FAILURE; + } + + devp->flash->ADDR = (uint32_t)address; + + sn32_flash_wait_busy(devp); + + /* Actual program implementation.*/ + do { + // Programming line + devp->flash->DATA = *((uint32_t *)pp); + sn32_flash_wait_busy(devp); + + // Move to the next data and address + pp += SN32_FLASH_LINE_SIZE; + offset += SN32_FLASH_LINE_SIZE; + n -= SN32_FLASH_LINE_SIZE; + } + while ((n > 0U) & ((offset & SN32_FLASH_LINE_MASK) != 0U)); + + err = sn32_flash_check_errors(devp); + if (err != FLASH_NO_ERROR) { + return err; + } + // Programming start + sn32_flash_start_pgm(devp); + sn32_flash_wait_busy(devp); + err = sn32_flash_check_errors(devp); + if (err != FLASH_NO_ERROR) { + return err; + } + + /* Ready state again.*/ + devp->state = FLASH_READY; + + return err; +} + +/** + * @brief Starts a whole-device erase operation. + * @note This function only erases bank 2 if it is present. Bank 1 is not + * allowed since it is normally where the primary program is located. + * Pages on bank 1 can be individually erased. + * + * @param[in] ip pointer to a @p EFlashDriver instance + * @return An error code. + * @retval FLASH_NO_ERROR if there is no erase operation in progress. + * @retval FLASH_BUSY_ERASING if there is an erase operation in progress. + * @retval FLASH_ERROR_HW_FAILURE if access to the memory failed. + * + * @notapi + */ +flash_error_t efl_lld_start_erase_all(void *instance) { + (void) instance; + + return FLASH_ERROR_UNIMPLEMENTED; +} + +/** + * @brief Starts an sector erase operation. + * + * @param[in] ip pointer to a @p EFlashDriver instance + * @param[in] sector sector to be erased + * this is an index within the total sectors + * in a flash bank + * @return An error code. + * @retval FLASH_NO_ERROR if there is no erase operation in progress. + * @retval FLASH_BUSY_ERASING if there is an erase operation in progress. + * @retval FLASH_ERROR_HW_FAILURE if access to the memory failed. + * + * @notapi + */ +flash_error_t efl_lld_start_erase_sector(void *instance, + flash_sector_t sector) { + EFlashDriver *devp = (EFlashDriver *)instance; + + osalDbgCheck(instance != NULL); + osalDbgCheck(sector < efl_lld_descriptor.sectors_count); + osalDbgAssert((devp->state == FLASH_READY) || (devp->state == FLASH_ERASE), + "invalid state"); + + /* No erasing while erasing.*/ + if (devp->state == FLASH_ERASE) { + return FLASH_BUSY_ERASING; + } + + /* FLASH_PGM state while the operation is performed.*/ + devp->state = FLASH_ERASE; + + /* Clearing error status bits.*/ + sn32_flash_clear_status(devp); + + /* Enable page erase.*/ + devp->flash->CTRL = SN32_FLASH_CTRL_PER; + + /* Set the page.*/ + devp->flash->ADDR = (uint32_t)(efl_lld_descriptor.address + + flashGetSectorOffset(getBaseFlash(devp), sector)); + sn32_flash_wait_busy(devp); + + /* Start the erase.*/ + sn32_flash_start_pgm(devp); + sn32_flash_wait_busy(devp); + return FLASH_NO_ERROR; +} + +/** + * @brief Queries the driver for erase operation progress. + * + * @param[in] ip pointer to a @p EFlashDriver instance + * @param[out] msec recommended time, in milliseconds, that + * should be spent before calling this + * function again, can be @p NULL + * @return An error code. + * @retval FLASH_NO_ERROR if there is no erase operation in progress. + * @retval FLASH_BUSY_ERASING if there is an erase operation in progress. + * @retval FLASH_ERROR_ERASE if the erase operation failed. + * @retval FLASH_ERROR_HW_FAILURE if access to the memory failed. + * + * @api + */ +flash_error_t efl_lld_query_erase(void *instance, uint32_t *msec) { + EFlashDriver *devp = (EFlashDriver *)instance; + flash_error_t err = FLASH_NO_ERROR; + + /* If there is an erase in progress then the device must be checked.*/ + if (devp->state == FLASH_ERASE) { + + /* Checking for operation in progress.*/ + if ((devp->flash->STATUS & SN32_FLASH_STATUS_BUSY) == 0U) { + + /* Disabling the various erase control bits.*/ + devp->flash->CTRL &= ~(SN32_FLASH_CTRL_PER | SN32_FLASH_CTRL_MER); + + /* Back to ready state.*/ + devp->state = FLASH_READY; + } + else { + /* Recommended time before polling again. This is a simplified + implementation.*/ + if (msec != NULL) { + *msec = (uint32_t)SN32_FLASH_WAIT_TIME_MS; + } + + err = FLASH_BUSY_ERASING; + } + } + + return err; +} + +/** + * @brief Returns the erase state of a sector. + * + * @param[in] ip pointer to a @p EFlashDriver instance + * @param[in] sector sector to be verified + * @return An error code. + * @retval FLASH_NO_ERROR if the sector is erased. + * @retval FLASH_BUSY_ERASING if there is an erase operation in progress. + * @retval FLASH_ERROR_VERIFY if the verify operation failed. + * @retval FLASH_ERROR_HW_FAILURE if access to the memory failed. + * + * @notapi + */ +flash_error_t efl_lld_verify_erase(void *instance, flash_sector_t sector) { + EFlashDriver *devp = (EFlashDriver *)instance; + uint32_t *address; + flash_error_t err = FLASH_NO_ERROR; + unsigned i; + + osalDbgCheck(instance != NULL); + osalDbgCheck(sector < efl_lld_descriptor.sectors_count); + osalDbgAssert((devp->state == FLASH_READY) || (devp->state == FLASH_ERASE), + "invalid state"); + + /* No verifying while erasing.*/ + if (devp->state == FLASH_ERASE) { + return FLASH_BUSY_ERASING; + } + + /* Address of the sector.*/ + address = (uint32_t *)(SN32_FLASH_BASE + + flashGetSectorOffset(getBaseFlash(devp), sector)); + + /* FLASH_READ state while the operation is performed.*/ + devp->state = FLASH_READ; + + /* Scanning the sector space.*/ + uint32_t sector_size = flashGetSectorSize(getBaseFlash(devp), sector); + for (i = 0U; i < sector_size / sizeof(uint32_t); i++) { + if (*address != 0x00000000U) { + err = FLASH_ERROR_VERIFY; + break; + } + address++; + } + + /* Ready state again.*/ + devp->state = FLASH_READY; + + return err; +} + +#endif /* HAL_USE_EFL == TRUE */ + +/** @} */ diff --git a/os/hal/ports/SN32/SN32F240/hal_efl_lld.h b/os/hal/ports/SN32/SN32F240/hal_efl_lld.h new file mode 100644 index 0000000000..348ba983c1 --- /dev/null +++ b/os/hal/ports/SN32/SN32F240/hal_efl_lld.h @@ -0,0 +1,129 @@ +/* + ChibiOS - Copyright (C) 2006..2023 Giovanni Di Sirio + Copyright (C) 2023 Dimitris Mantzouranis + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +*/ + +/** + * @file hal_efl_lld.h + * @brief SN32F24xB Embedded Flash subsystem low level driver header. + * + * @addtogroup HAL_EFL + * @{ + */ + +#ifndef HAL_EFL_LLD_H +#define HAL_EFL_LLD_H + +#if (HAL_USE_EFL == TRUE) || defined(__DOXYGEN__) + +/*===========================================================================*/ +/* Driver constants. */ +/*===========================================================================*/ +#define SN32_FLASH_CTRL_PG 0x00000001 +#define SN32_FLASH_CTRL_PER 0x00000002 +#define SN32_FLASH_CTRL_MER 0x00000004 +#define SN32_FLASH_CTRL_START 0x00000040 +#define SN32_FLASH_CTRL_CHK 0x00000080 + +#define SN32_FLASH_STATUS_BUSY 0x00000001 +#define SN32_FLASH_STATUS_ERROR 0x00000004 + +/*===========================================================================*/ +/* Driver pre-compile time settings. */ +/*===========================================================================*/ + +/** + * @name SN32F24xB configuration options + * @{ + */ +/** + * @brief Suggested wait time during erase operations polling. + */ +#if !defined(SN32_FLASH_WAIT_TIME_MS) || defined(__DOXYGEN__) +#define SN32_FLASH_WAIT_TIME_MS 1 +#endif +/** @} */ + +/*===========================================================================*/ +/* Derived constants and error checks. */ +/*===========================================================================*/ + +#if !defined(SN32_FLASH_SECTOR_SIZE) +#error "SN32_FLASH_SECTOR_SIZE not defined in registry" +#endif + +#if !defined(SN32_FLASH_NUMBER_OF_BANKS) +#error "SN32_FLASH_NUMBER_OF_BANKS not defined in registry" +#endif + +#if !defined(SN32_FLASH_SECTORS_PER_BANK) +#error "SN32_FLASH_SECTORS_PER_BANK not defined in registry" +#endif + +/*===========================================================================*/ +/* Driver data structures and types. */ +/*===========================================================================*/ + +/*===========================================================================*/ +/* Driver macros. */ +/*===========================================================================*/ + +/** + * @brief Low level fields of the embedded flash driver structure. + */ +#define efl_lld_driver_fields \ + /* Flash registers.*/ \ + SN_FLASH_Type *flash + +/** + * @brief Low level fields of the embedded flash configuration structure. + */ +#define efl_lld_config_fields \ + /* Dummy configuration, it is not needed.*/ \ + uint32_t dummy + +/*===========================================================================*/ +/* External declarations. */ +/*===========================================================================*/ + +#if !defined(__DOXYGEN__) +extern EFlashDriver EFLD1; +#endif + +#ifdef __cplusplus +extern "C" { +#endif + void efl_lld_init(void); + void efl_lld_start(EFlashDriver *eflp); + void efl_lld_stop(EFlashDriver *eflp); + const flash_descriptor_t *efl_lld_get_descriptor(void *instance); + flash_error_t efl_lld_read(void *instance, flash_offset_t offset, + size_t n, uint8_t *rp); + flash_error_t efl_lld_program(void *instance, flash_offset_t offset, + size_t n, const uint8_t *pp); + flash_error_t efl_lld_start_erase_all(void *instance); + flash_error_t efl_lld_start_erase_sector(void *instance, + flash_sector_t sector); + flash_error_t efl_lld_query_erase(void *instance, uint32_t *wait_time); + flash_error_t efl_lld_verify_erase(void *instance, flash_sector_t sector); +#ifdef __cplusplus +} +#endif + +#endif /* HAL_USE_EFL == TRUE */ + +#endif /* HAL_EFL_LLD_H */ + +/** @} */ diff --git a/os/hal/ports/SN32/SN32F240/platform.mk b/os/hal/ports/SN32/SN32F240/platform.mk index e604cb35ad..58b75cbd19 100644 --- a/os/hal/ports/SN32/SN32F240/platform.mk +++ b/os/hal/ports/SN32/SN32F240/platform.mk @@ -1,6 +1,7 @@ # Required platform files. PLATFORMSRC_CONTRIB := $(CHIBIOS)/os/hal/ports/common/ARMCMx/nvic.c \ - $(CHIBIOS_CONTRIB)/os/hal/ports/SN32/SN32F240/hal_lld.c + $(CHIBIOS_CONTRIB)/os/hal/ports/SN32/SN32F240/hal_lld.c \ + $(CHIBIOS_CONTRIB)/os/hal/ports/SN32/SN32F240/hal_efl_lld.c # Required include directories. PLATFORMINC_CONTRIB := $(CHIBIOS)/os/hal/ports/common/ARMCMx \ diff --git a/os/hal/ports/SN32/SN32F240/sn32_registry.h b/os/hal/ports/SN32/SN32F240/sn32_registry.h index 4a27266318..aaa9c80a07 100644 --- a/os/hal/ports/SN32/SN32F240/sn32_registry.h +++ b/os/hal/ports/SN32/SN32F240/sn32_registry.h @@ -162,6 +162,16 @@ #define SN32_HAS_GPIOB TRUE #define SN32_HAS_GPIOA TRUE +/* + * FLASH units. + */ +#define SN32_JUMPLOADER_SIZE 0x200 +#define SN32_FLASH_LINE_SIZE 4U +#define SN32_FLASH_NUMBER_OF_BANKS 1 +#define SN32_FLASH_SECTORS_PER_BANK 64U +#define SN32_FLASH_SECTOR_SIZE 1024U +#define SN32_FLASH_BASE 0x00000000UL +#define FLASH_SIZE (SN32_FLASH_NUMBER_OF_BANKS * SN32_FLASH_SECTORS_PER_BANK * SN32_FLASH_SECTOR_SIZE) /*===========================================================================*/ /* Common. */ /*===========================================================================*/ diff --git a/os/hal/ports/SN32/SN32F240B/hal_efl_lld.c b/os/hal/ports/SN32/SN32F240B/hal_efl_lld.c new file mode 100644 index 0000000000..b6ef39fe50 --- /dev/null +++ b/os/hal/ports/SN32/SN32F240B/hal_efl_lld.c @@ -0,0 +1,462 @@ +/* + ChibiOS - Copyright (C) 2006..2023 Giovanni Di Sirio + Copyright (C) 2023 Dimitris Mantzouranis + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +*/ + +/** + * @file hal_efl_lld.c + * @brief SN32F24xB Embedded Flash subsystem low level driver source. + * + * @addtogroup HAL_EFL + * @{ + */ + +#include + +#include "hal.h" + +#if (HAL_USE_EFL == TRUE) || defined(__DOXYGEN__) + +/*===========================================================================*/ +/* Driver local definitions. */ +/*===========================================================================*/ + +#define SN32_FLASH_LINE_MASK (SN32_FLASH_LINE_SIZE - 1U) + +/*===========================================================================*/ +/* Driver exported variables. */ +/*===========================================================================*/ + +/** + * @brief EFL1 driver identifier. + */ +EFlashDriver EFLD1; + +/*===========================================================================*/ +/* Driver local variables and types. */ +/*===========================================================================*/ + +static const flash_descriptor_t efl_lld_descriptor = { + .attributes = FLASH_ATTR_MEMORY_MAPPED, + .page_size = SN32_FLASH_LINE_SIZE, + .sectors_count = SN32_FLASH_NUMBER_OF_BANKS * + SN32_FLASH_SECTORS_PER_BANK, + .sectors = NULL, + .sectors_size = SN32_FLASH_SECTOR_SIZE, + .address = (uint8_t *)SN32_FLASH_BASE, + .size = SN32_FLASH_NUMBER_OF_BANKS * + SN32_FLASH_SECTORS_PER_BANK * + SN32_FLASH_SECTOR_SIZE +}; + +/*===========================================================================*/ +/* Driver local functions. */ +/*===========================================================================*/ + +static inline void sn32_flash_enable_pgm(EFlashDriver *eflp) { + + eflp->flash->CTRL = SN32_FLASH_CTRL_PG; +} + +static inline void sn32_flash_start_pgm(EFlashDriver *eflp) { + + eflp->flash->CTRL |= SN32_FLASH_CTRL_START; +} + +static inline void sn32_flash_clear_status(EFlashDriver *eflp) { + + /* Clearing error conditions.*/ + eflp->flash->STATUS_b.ERR = 0; +} + +static inline void sn32_flash_wait_busy(EFlashDriver *eflp) { + + /* Wait for busy bit clear.*/ + while ((eflp->flash->STATUS & SN32_FLASH_STATUS_BUSY) != 0U) { + } +} + +static inline flash_error_t sn32_flash_check_errors(EFlashDriver *eflp) { + uint32_t error = eflp->flash->STATUS_b.ERR; + + /* Clearing error conditions.*/ + eflp->flash->STATUS_b.ERR = 0; + + /* Decoding relevant errors.*/ + if ((error) != 0U) { + return FLASH_ERROR_HW_FAILURE; + } + + return FLASH_NO_ERROR; +} + +/*===========================================================================*/ +/* Driver interrupt handlers. */ +/*===========================================================================*/ + +/*===========================================================================*/ +/* Driver exported functions. */ +/*===========================================================================*/ + +/** + * @brief Low level Embedded Flash driver initialization. + * + * @notapi + */ +void efl_lld_init(void) { + + /* Driver initialization.*/ + eflObjectInit(&EFLD1); + EFLD1.flash = SN_FLASH; +} + +/** + * @brief Configures and activates the Embedded Flash peripheral. + * + * @param[in] eflp pointer to a @p EFlashDriver structure + * + * @notapi + */ +void efl_lld_start(EFlashDriver *eflp) { + eflp->flash->CTRL = 0x00000000U; +} + +/** + * @brief Deactivates the Embedded Flash peripheral. + * + * @param[in] eflp pointer to a @p EFlashDriver structure + * + * @notapi + */ +void efl_lld_stop(EFlashDriver *eflp) { + +} + +/** + * @brief Gets the flash descriptor structure. + * + * @param[in] ip pointer to a @p EFlashDriver instance + * @return A flash device descriptor. + * @retval Pointer to single bank if DBM not enabled. + * @retval Pointer to bank1 if DBM enabled. + * + * @notapi + */ +const flash_descriptor_t *efl_lld_get_descriptor(void *instance) { + + (void)instance; + + return &efl_lld_descriptor; +} + +/** + * @brief Read operation. + * + * @param[in] ip pointer to a @p EFlashDriver instance + * @param[in] offset offset within full flash address space + * @param[in] n number of bytes to be read + * @param[out] rp pointer to the data buffer + * @return An error code. + * @retval FLASH_NO_ERROR if there is no erase operation in progress. + * @retval FLASH_BUSY_ERASING if there is an erase operation in progress. + * @retval FLASH_ERROR_READ if the read operation failed. + * @retval FLASH_ERROR_HW_FAILURE if access to the memory failed. + * + * @notapi + */ +flash_error_t efl_lld_read(void *instance, flash_offset_t offset, + size_t n, uint8_t *rp) { + EFlashDriver *devp = (EFlashDriver *)instance; + flash_error_t err = FLASH_NO_ERROR; + + osalDbgCheck((instance != NULL) && (rp != NULL) && (n > 0U)); + osalDbgCheck((size_t)offset + n <= (size_t)efl_lld_descriptor.size); + osalDbgAssert((devp->state == FLASH_READY) || (devp->state == FLASH_ERASE), + "invalid state"); + + /* No reading while erasing.*/ + if (devp->state == FLASH_ERASE) { + return FLASH_BUSY_ERASING; + } + + /* FLASH_READ state while the operation is performed.*/ + devp->state = FLASH_READ; + + /* Clearing error status bits.*/ + sn32_flash_clear_status(devp); + + /* Actual read implementation.*/ + memcpy((void *)rp, (const void *)efl_lld_descriptor.address + offset, n); + + /* Ready state again.*/ + devp->state = FLASH_READY; + + return err; +} + +/** + * @brief Program operation. + * @note The device supports ECC, it is only possible to write erased + * pages once except when writing all zeroes. + * + * @param[in] ip pointer to a @p EFlashDriver instance + * @param[in] offset offset within full flash address space + * @param[in] n number of bytes to be programmed + * @param[in] pp pointer to the data buffer + * @return An error code. + * @retval FLASH_NO_ERROR if there is no erase operation in progress. + * @retval FLASH_BUSY_ERASING if there is an erase operation in progress. + * @retval FLASH_ERROR_PROGRAM if the program operation failed. + * @retval FLASH_ERROR_HW_FAILURE if access to the memory failed. + * + * @notapi + */ + +flash_error_t efl_lld_program(void *instance, flash_offset_t offset, + size_t n, const uint8_t *pp) { + EFlashDriver *devp = (EFlashDriver *)instance; + flash_error_t err = FLASH_NO_ERROR; + volatile uint32_t *address; + + osalDbgCheck((instance != NULL) && (pp != NULL) && (n > 0U)); + osalDbgCheck((size_t)offset + n <= (size_t)efl_lld_descriptor.size); + osalDbgAssert((devp->state == FLASH_READY) || (devp->state == FLASH_ERASE), + "invalid state"); + + /* No programming while erasing.*/ + if (devp->state == FLASH_ERASE) { + return FLASH_BUSY_ERASING; + } + + /* FLASH_PGM state while the operation is performed.*/ + devp->state = FLASH_PGM; + + /* Clearing error status bits.*/ + sn32_flash_clear_status(devp); + + /* Enabling PGM mode in the controller.*/ + sn32_flash_enable_pgm(devp); + + /* Calculate the address from the offset. */ + address = (volatile uint32_t *)(efl_lld_descriptor.address + + (offset & ~SN32_FLASH_LINE_MASK)); + + if (address < (volatile uint32_t *)SN32_JUMPLOADER_SIZE) { + return FLASH_ERROR_HW_FAILURE; + } + + devp->flash->ADDR = (uint32_t)address; + + sn32_flash_wait_busy(devp); + + /* Actual program implementation.*/ + do { + // Programming line + devp->flash->DATA = *((uint32_t *)pp); + sn32_flash_wait_busy(devp); + + // Move to the next data and address + pp += SN32_FLASH_LINE_SIZE; + offset += SN32_FLASH_LINE_SIZE; + n -= SN32_FLASH_LINE_SIZE; + } + while ((n > 0U) & ((offset & SN32_FLASH_LINE_MASK) != 0U)); + + err = sn32_flash_check_errors(devp); + if (err != FLASH_NO_ERROR) { + return err; + } + // Programming start + sn32_flash_start_pgm(devp); + sn32_flash_wait_busy(devp); + err = sn32_flash_check_errors(devp); + if (err != FLASH_NO_ERROR) { + return err; + } + + /* Ready state again.*/ + devp->state = FLASH_READY; + + return err; +} + +/** + * @brief Starts a whole-device erase operation. + * @note This function only erases bank 2 if it is present. Bank 1 is not + * allowed since it is normally where the primary program is located. + * Pages on bank 1 can be individually erased. + * + * @param[in] ip pointer to a @p EFlashDriver instance + * @return An error code. + * @retval FLASH_NO_ERROR if there is no erase operation in progress. + * @retval FLASH_BUSY_ERASING if there is an erase operation in progress. + * @retval FLASH_ERROR_HW_FAILURE if access to the memory failed. + * + * @notapi + */ +flash_error_t efl_lld_start_erase_all(void *instance) { + (void) instance; + + return FLASH_ERROR_UNIMPLEMENTED; +} + +/** + * @brief Starts an sector erase operation. + * + * @param[in] ip pointer to a @p EFlashDriver instance + * @param[in] sector sector to be erased + * this is an index within the total sectors + * in a flash bank + * @return An error code. + * @retval FLASH_NO_ERROR if there is no erase operation in progress. + * @retval FLASH_BUSY_ERASING if there is an erase operation in progress. + * @retval FLASH_ERROR_HW_FAILURE if access to the memory failed. + * + * @notapi + */ +flash_error_t efl_lld_start_erase_sector(void *instance, + flash_sector_t sector) { + EFlashDriver *devp = (EFlashDriver *)instance; + + osalDbgCheck(instance != NULL); + osalDbgCheck(sector < efl_lld_descriptor.sectors_count); + osalDbgAssert((devp->state == FLASH_READY) || (devp->state == FLASH_ERASE), + "invalid state"); + + /* No erasing while erasing.*/ + if (devp->state == FLASH_ERASE) { + return FLASH_BUSY_ERASING; + } + + /* FLASH_PGM state while the operation is performed.*/ + devp->state = FLASH_ERASE; + + /* Clearing error status bits.*/ + sn32_flash_clear_status(devp); + + /* Enable page erase.*/ + devp->flash->CTRL = SN32_FLASH_CTRL_PER; + + /* Set the page.*/ + devp->flash->ADDR = (uint32_t)(efl_lld_descriptor.address + + flashGetSectorOffset(getBaseFlash(devp), sector)); + sn32_flash_wait_busy(devp); + + /* Start the erase.*/ + sn32_flash_start_pgm(devp); + sn32_flash_wait_busy(devp); + return FLASH_NO_ERROR; +} + +/** + * @brief Queries the driver for erase operation progress. + * + * @param[in] ip pointer to a @p EFlashDriver instance + * @param[out] msec recommended time, in milliseconds, that + * should be spent before calling this + * function again, can be @p NULL + * @return An error code. + * @retval FLASH_NO_ERROR if there is no erase operation in progress. + * @retval FLASH_BUSY_ERASING if there is an erase operation in progress. + * @retval FLASH_ERROR_ERASE if the erase operation failed. + * @retval FLASH_ERROR_HW_FAILURE if access to the memory failed. + * + * @api + */ +flash_error_t efl_lld_query_erase(void *instance, uint32_t *msec) { + EFlashDriver *devp = (EFlashDriver *)instance; + flash_error_t err = FLASH_NO_ERROR; + + /* If there is an erase in progress then the device must be checked.*/ + if (devp->state == FLASH_ERASE) { + + /* Checking for operation in progress.*/ + if ((devp->flash->STATUS & SN32_FLASH_STATUS_BUSY) == 0U) { + + /* Disabling the various erase control bits.*/ + devp->flash->CTRL &= ~(SN32_FLASH_CTRL_PER | SN32_FLASH_CTRL_MER); + + /* Back to ready state.*/ + devp->state = FLASH_READY; + } + else { + /* Recommended time before polling again. This is a simplified + implementation.*/ + if (msec != NULL) { + *msec = (uint32_t)SN32_FLASH_WAIT_TIME_MS; + } + + err = FLASH_BUSY_ERASING; + } + } + + return err; +} + +/** + * @brief Returns the erase state of a sector. + * + * @param[in] ip pointer to a @p EFlashDriver instance + * @param[in] sector sector to be verified + * @return An error code. + * @retval FLASH_NO_ERROR if the sector is erased. + * @retval FLASH_BUSY_ERASING if there is an erase operation in progress. + * @retval FLASH_ERROR_VERIFY if the verify operation failed. + * @retval FLASH_ERROR_HW_FAILURE if access to the memory failed. + * + * @notapi + */ +flash_error_t efl_lld_verify_erase(void *instance, flash_sector_t sector) { + EFlashDriver *devp = (EFlashDriver *)instance; + uint32_t *address; + flash_error_t err = FLASH_NO_ERROR; + unsigned i; + + osalDbgCheck(instance != NULL); + osalDbgCheck(sector < efl_lld_descriptor.sectors_count); + osalDbgAssert((devp->state == FLASH_READY) || (devp->state == FLASH_ERASE), + "invalid state"); + + /* No verifying while erasing.*/ + if (devp->state == FLASH_ERASE) { + return FLASH_BUSY_ERASING; + } + + /* Address of the sector.*/ + address = (uint32_t *)(SN32_FLASH_BASE + + flashGetSectorOffset(getBaseFlash(devp), sector)); + + /* FLASH_READ state while the operation is performed.*/ + devp->state = FLASH_READ; + + /* Scanning the sector space.*/ + uint32_t sector_size = flashGetSectorSize(getBaseFlash(devp), sector); + for (i = 0U; i < sector_size / sizeof(uint32_t); i++) { + if (*address != 0x00000000U) { + err = FLASH_ERROR_VERIFY; + break; + } + address++; + } + + /* Ready state again.*/ + devp->state = FLASH_READY; + + return err; +} + +#endif /* HAL_USE_EFL == TRUE */ + +/** @} */ diff --git a/os/hal/ports/SN32/SN32F240B/hal_efl_lld.h b/os/hal/ports/SN32/SN32F240B/hal_efl_lld.h new file mode 100644 index 0000000000..348ba983c1 --- /dev/null +++ b/os/hal/ports/SN32/SN32F240B/hal_efl_lld.h @@ -0,0 +1,129 @@ +/* + ChibiOS - Copyright (C) 2006..2023 Giovanni Di Sirio + Copyright (C) 2023 Dimitris Mantzouranis + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +*/ + +/** + * @file hal_efl_lld.h + * @brief SN32F24xB Embedded Flash subsystem low level driver header. + * + * @addtogroup HAL_EFL + * @{ + */ + +#ifndef HAL_EFL_LLD_H +#define HAL_EFL_LLD_H + +#if (HAL_USE_EFL == TRUE) || defined(__DOXYGEN__) + +/*===========================================================================*/ +/* Driver constants. */ +/*===========================================================================*/ +#define SN32_FLASH_CTRL_PG 0x00000001 +#define SN32_FLASH_CTRL_PER 0x00000002 +#define SN32_FLASH_CTRL_MER 0x00000004 +#define SN32_FLASH_CTRL_START 0x00000040 +#define SN32_FLASH_CTRL_CHK 0x00000080 + +#define SN32_FLASH_STATUS_BUSY 0x00000001 +#define SN32_FLASH_STATUS_ERROR 0x00000004 + +/*===========================================================================*/ +/* Driver pre-compile time settings. */ +/*===========================================================================*/ + +/** + * @name SN32F24xB configuration options + * @{ + */ +/** + * @brief Suggested wait time during erase operations polling. + */ +#if !defined(SN32_FLASH_WAIT_TIME_MS) || defined(__DOXYGEN__) +#define SN32_FLASH_WAIT_TIME_MS 1 +#endif +/** @} */ + +/*===========================================================================*/ +/* Derived constants and error checks. */ +/*===========================================================================*/ + +#if !defined(SN32_FLASH_SECTOR_SIZE) +#error "SN32_FLASH_SECTOR_SIZE not defined in registry" +#endif + +#if !defined(SN32_FLASH_NUMBER_OF_BANKS) +#error "SN32_FLASH_NUMBER_OF_BANKS not defined in registry" +#endif + +#if !defined(SN32_FLASH_SECTORS_PER_BANK) +#error "SN32_FLASH_SECTORS_PER_BANK not defined in registry" +#endif + +/*===========================================================================*/ +/* Driver data structures and types. */ +/*===========================================================================*/ + +/*===========================================================================*/ +/* Driver macros. */ +/*===========================================================================*/ + +/** + * @brief Low level fields of the embedded flash driver structure. + */ +#define efl_lld_driver_fields \ + /* Flash registers.*/ \ + SN_FLASH_Type *flash + +/** + * @brief Low level fields of the embedded flash configuration structure. + */ +#define efl_lld_config_fields \ + /* Dummy configuration, it is not needed.*/ \ + uint32_t dummy + +/*===========================================================================*/ +/* External declarations. */ +/*===========================================================================*/ + +#if !defined(__DOXYGEN__) +extern EFlashDriver EFLD1; +#endif + +#ifdef __cplusplus +extern "C" { +#endif + void efl_lld_init(void); + void efl_lld_start(EFlashDriver *eflp); + void efl_lld_stop(EFlashDriver *eflp); + const flash_descriptor_t *efl_lld_get_descriptor(void *instance); + flash_error_t efl_lld_read(void *instance, flash_offset_t offset, + size_t n, uint8_t *rp); + flash_error_t efl_lld_program(void *instance, flash_offset_t offset, + size_t n, const uint8_t *pp); + flash_error_t efl_lld_start_erase_all(void *instance); + flash_error_t efl_lld_start_erase_sector(void *instance, + flash_sector_t sector); + flash_error_t efl_lld_query_erase(void *instance, uint32_t *wait_time); + flash_error_t efl_lld_verify_erase(void *instance, flash_sector_t sector); +#ifdef __cplusplus +} +#endif + +#endif /* HAL_USE_EFL == TRUE */ + +#endif /* HAL_EFL_LLD_H */ + +/** @} */ diff --git a/os/hal/ports/SN32/SN32F240B/platform.mk b/os/hal/ports/SN32/SN32F240B/platform.mk index 309a76ac34..24ad660945 100644 --- a/os/hal/ports/SN32/SN32F240B/platform.mk +++ b/os/hal/ports/SN32/SN32F240B/platform.mk @@ -1,6 +1,7 @@ # Required platform files. PLATFORMSRC_CONTRIB := $(CHIBIOS)/os/hal/ports/common/ARMCMx/nvic.c \ - $(CHIBIOS_CONTRIB)/os/hal/ports/SN32/SN32F240B/hal_lld.c + $(CHIBIOS_CONTRIB)/os/hal/ports/SN32/SN32F240B/hal_lld.c \ + $(CHIBIOS_CONTRIB)/os/hal/ports/SN32/SN32F240B/hal_efl_lld.c # Required include directories. PLATFORMINC_CONTRIB := $(CHIBIOS)/os/hal/ports/common/ARMCMx \ @@ -22,7 +23,6 @@ endif include ${CHIBIOS_CONTRIB}/os/hal/ports/SN32/LLD/SN32F2xx/GPIO/driver.mk include ${CHIBIOS_CONTRIB}/os/hal/ports/SN32/LLD/SN32F2xx/USB/driver.mk include ${CHIBIOS_CONTRIB}/os/hal/ports/SN32/LLD/SN32F2xx/CT/driver.mk -include ${CHIBIOS_CONTRIB}/os/hal/ports/SN32/LLD/SN32F2xx/FLASH/driver.mk include ${CHIBIOS_CONTRIB}/os/hal/ports/SN32/LLD/SN32F2xx/SysTick/driver.mk include ${CHIBIOS_CONTRIB}/os/hal/ports/SN32/LLD/SN32F2xx/SPI/driver.mk include ${CHIBIOS_CONTRIB}/os/hal/ports/SN32/LLD/SN32F2xx/I2C/driver.mk diff --git a/os/hal/ports/SN32/SN32F240B/sn32_registry.h b/os/hal/ports/SN32/SN32F240B/sn32_registry.h index 25d9454a55..f337bb68d4 100644 --- a/os/hal/ports/SN32/SN32F240B/sn32_registry.h +++ b/os/hal/ports/SN32/SN32F240B/sn32_registry.h @@ -144,6 +144,16 @@ #define SN32_HAS_GPIOB TRUE #define SN32_HAS_GPIOA TRUE +/* + * FLASH units. + */ +#define SN32_JUMPLOADER_SIZE 0x200 +#define SN32_FLASH_LINE_SIZE 4U +#define SN32_FLASH_NUMBER_OF_BANKS 1 +#define SN32_FLASH_SECTORS_PER_BANK 1024U +#define SN32_FLASH_SECTOR_SIZE 64U +#define SN32_FLASH_BASE 0x00000000UL +#define FLASH_SIZE (SN32_FLASH_NUMBER_OF_BANKS * SN32_FLASH_SECTORS_PER_BANK * SN32_FLASH_SECTOR_SIZE) /*===========================================================================*/ /* Common. */ /*===========================================================================*/ diff --git a/os/hal/ports/SN32/SN32F260/hal_efl_lld.c b/os/hal/ports/SN32/SN32F260/hal_efl_lld.c new file mode 100644 index 0000000000..b6ef39fe50 --- /dev/null +++ b/os/hal/ports/SN32/SN32F260/hal_efl_lld.c @@ -0,0 +1,462 @@ +/* + ChibiOS - Copyright (C) 2006..2023 Giovanni Di Sirio + Copyright (C) 2023 Dimitris Mantzouranis + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +*/ + +/** + * @file hal_efl_lld.c + * @brief SN32F24xB Embedded Flash subsystem low level driver source. + * + * @addtogroup HAL_EFL + * @{ + */ + +#include + +#include "hal.h" + +#if (HAL_USE_EFL == TRUE) || defined(__DOXYGEN__) + +/*===========================================================================*/ +/* Driver local definitions. */ +/*===========================================================================*/ + +#define SN32_FLASH_LINE_MASK (SN32_FLASH_LINE_SIZE - 1U) + +/*===========================================================================*/ +/* Driver exported variables. */ +/*===========================================================================*/ + +/** + * @brief EFL1 driver identifier. + */ +EFlashDriver EFLD1; + +/*===========================================================================*/ +/* Driver local variables and types. */ +/*===========================================================================*/ + +static const flash_descriptor_t efl_lld_descriptor = { + .attributes = FLASH_ATTR_MEMORY_MAPPED, + .page_size = SN32_FLASH_LINE_SIZE, + .sectors_count = SN32_FLASH_NUMBER_OF_BANKS * + SN32_FLASH_SECTORS_PER_BANK, + .sectors = NULL, + .sectors_size = SN32_FLASH_SECTOR_SIZE, + .address = (uint8_t *)SN32_FLASH_BASE, + .size = SN32_FLASH_NUMBER_OF_BANKS * + SN32_FLASH_SECTORS_PER_BANK * + SN32_FLASH_SECTOR_SIZE +}; + +/*===========================================================================*/ +/* Driver local functions. */ +/*===========================================================================*/ + +static inline void sn32_flash_enable_pgm(EFlashDriver *eflp) { + + eflp->flash->CTRL = SN32_FLASH_CTRL_PG; +} + +static inline void sn32_flash_start_pgm(EFlashDriver *eflp) { + + eflp->flash->CTRL |= SN32_FLASH_CTRL_START; +} + +static inline void sn32_flash_clear_status(EFlashDriver *eflp) { + + /* Clearing error conditions.*/ + eflp->flash->STATUS_b.ERR = 0; +} + +static inline void sn32_flash_wait_busy(EFlashDriver *eflp) { + + /* Wait for busy bit clear.*/ + while ((eflp->flash->STATUS & SN32_FLASH_STATUS_BUSY) != 0U) { + } +} + +static inline flash_error_t sn32_flash_check_errors(EFlashDriver *eflp) { + uint32_t error = eflp->flash->STATUS_b.ERR; + + /* Clearing error conditions.*/ + eflp->flash->STATUS_b.ERR = 0; + + /* Decoding relevant errors.*/ + if ((error) != 0U) { + return FLASH_ERROR_HW_FAILURE; + } + + return FLASH_NO_ERROR; +} + +/*===========================================================================*/ +/* Driver interrupt handlers. */ +/*===========================================================================*/ + +/*===========================================================================*/ +/* Driver exported functions. */ +/*===========================================================================*/ + +/** + * @brief Low level Embedded Flash driver initialization. + * + * @notapi + */ +void efl_lld_init(void) { + + /* Driver initialization.*/ + eflObjectInit(&EFLD1); + EFLD1.flash = SN_FLASH; +} + +/** + * @brief Configures and activates the Embedded Flash peripheral. + * + * @param[in] eflp pointer to a @p EFlashDriver structure + * + * @notapi + */ +void efl_lld_start(EFlashDriver *eflp) { + eflp->flash->CTRL = 0x00000000U; +} + +/** + * @brief Deactivates the Embedded Flash peripheral. + * + * @param[in] eflp pointer to a @p EFlashDriver structure + * + * @notapi + */ +void efl_lld_stop(EFlashDriver *eflp) { + +} + +/** + * @brief Gets the flash descriptor structure. + * + * @param[in] ip pointer to a @p EFlashDriver instance + * @return A flash device descriptor. + * @retval Pointer to single bank if DBM not enabled. + * @retval Pointer to bank1 if DBM enabled. + * + * @notapi + */ +const flash_descriptor_t *efl_lld_get_descriptor(void *instance) { + + (void)instance; + + return &efl_lld_descriptor; +} + +/** + * @brief Read operation. + * + * @param[in] ip pointer to a @p EFlashDriver instance + * @param[in] offset offset within full flash address space + * @param[in] n number of bytes to be read + * @param[out] rp pointer to the data buffer + * @return An error code. + * @retval FLASH_NO_ERROR if there is no erase operation in progress. + * @retval FLASH_BUSY_ERASING if there is an erase operation in progress. + * @retval FLASH_ERROR_READ if the read operation failed. + * @retval FLASH_ERROR_HW_FAILURE if access to the memory failed. + * + * @notapi + */ +flash_error_t efl_lld_read(void *instance, flash_offset_t offset, + size_t n, uint8_t *rp) { + EFlashDriver *devp = (EFlashDriver *)instance; + flash_error_t err = FLASH_NO_ERROR; + + osalDbgCheck((instance != NULL) && (rp != NULL) && (n > 0U)); + osalDbgCheck((size_t)offset + n <= (size_t)efl_lld_descriptor.size); + osalDbgAssert((devp->state == FLASH_READY) || (devp->state == FLASH_ERASE), + "invalid state"); + + /* No reading while erasing.*/ + if (devp->state == FLASH_ERASE) { + return FLASH_BUSY_ERASING; + } + + /* FLASH_READ state while the operation is performed.*/ + devp->state = FLASH_READ; + + /* Clearing error status bits.*/ + sn32_flash_clear_status(devp); + + /* Actual read implementation.*/ + memcpy((void *)rp, (const void *)efl_lld_descriptor.address + offset, n); + + /* Ready state again.*/ + devp->state = FLASH_READY; + + return err; +} + +/** + * @brief Program operation. + * @note The device supports ECC, it is only possible to write erased + * pages once except when writing all zeroes. + * + * @param[in] ip pointer to a @p EFlashDriver instance + * @param[in] offset offset within full flash address space + * @param[in] n number of bytes to be programmed + * @param[in] pp pointer to the data buffer + * @return An error code. + * @retval FLASH_NO_ERROR if there is no erase operation in progress. + * @retval FLASH_BUSY_ERASING if there is an erase operation in progress. + * @retval FLASH_ERROR_PROGRAM if the program operation failed. + * @retval FLASH_ERROR_HW_FAILURE if access to the memory failed. + * + * @notapi + */ + +flash_error_t efl_lld_program(void *instance, flash_offset_t offset, + size_t n, const uint8_t *pp) { + EFlashDriver *devp = (EFlashDriver *)instance; + flash_error_t err = FLASH_NO_ERROR; + volatile uint32_t *address; + + osalDbgCheck((instance != NULL) && (pp != NULL) && (n > 0U)); + osalDbgCheck((size_t)offset + n <= (size_t)efl_lld_descriptor.size); + osalDbgAssert((devp->state == FLASH_READY) || (devp->state == FLASH_ERASE), + "invalid state"); + + /* No programming while erasing.*/ + if (devp->state == FLASH_ERASE) { + return FLASH_BUSY_ERASING; + } + + /* FLASH_PGM state while the operation is performed.*/ + devp->state = FLASH_PGM; + + /* Clearing error status bits.*/ + sn32_flash_clear_status(devp); + + /* Enabling PGM mode in the controller.*/ + sn32_flash_enable_pgm(devp); + + /* Calculate the address from the offset. */ + address = (volatile uint32_t *)(efl_lld_descriptor.address + + (offset & ~SN32_FLASH_LINE_MASK)); + + if (address < (volatile uint32_t *)SN32_JUMPLOADER_SIZE) { + return FLASH_ERROR_HW_FAILURE; + } + + devp->flash->ADDR = (uint32_t)address; + + sn32_flash_wait_busy(devp); + + /* Actual program implementation.*/ + do { + // Programming line + devp->flash->DATA = *((uint32_t *)pp); + sn32_flash_wait_busy(devp); + + // Move to the next data and address + pp += SN32_FLASH_LINE_SIZE; + offset += SN32_FLASH_LINE_SIZE; + n -= SN32_FLASH_LINE_SIZE; + } + while ((n > 0U) & ((offset & SN32_FLASH_LINE_MASK) != 0U)); + + err = sn32_flash_check_errors(devp); + if (err != FLASH_NO_ERROR) { + return err; + } + // Programming start + sn32_flash_start_pgm(devp); + sn32_flash_wait_busy(devp); + err = sn32_flash_check_errors(devp); + if (err != FLASH_NO_ERROR) { + return err; + } + + /* Ready state again.*/ + devp->state = FLASH_READY; + + return err; +} + +/** + * @brief Starts a whole-device erase operation. + * @note This function only erases bank 2 if it is present. Bank 1 is not + * allowed since it is normally where the primary program is located. + * Pages on bank 1 can be individually erased. + * + * @param[in] ip pointer to a @p EFlashDriver instance + * @return An error code. + * @retval FLASH_NO_ERROR if there is no erase operation in progress. + * @retval FLASH_BUSY_ERASING if there is an erase operation in progress. + * @retval FLASH_ERROR_HW_FAILURE if access to the memory failed. + * + * @notapi + */ +flash_error_t efl_lld_start_erase_all(void *instance) { + (void) instance; + + return FLASH_ERROR_UNIMPLEMENTED; +} + +/** + * @brief Starts an sector erase operation. + * + * @param[in] ip pointer to a @p EFlashDriver instance + * @param[in] sector sector to be erased + * this is an index within the total sectors + * in a flash bank + * @return An error code. + * @retval FLASH_NO_ERROR if there is no erase operation in progress. + * @retval FLASH_BUSY_ERASING if there is an erase operation in progress. + * @retval FLASH_ERROR_HW_FAILURE if access to the memory failed. + * + * @notapi + */ +flash_error_t efl_lld_start_erase_sector(void *instance, + flash_sector_t sector) { + EFlashDriver *devp = (EFlashDriver *)instance; + + osalDbgCheck(instance != NULL); + osalDbgCheck(sector < efl_lld_descriptor.sectors_count); + osalDbgAssert((devp->state == FLASH_READY) || (devp->state == FLASH_ERASE), + "invalid state"); + + /* No erasing while erasing.*/ + if (devp->state == FLASH_ERASE) { + return FLASH_BUSY_ERASING; + } + + /* FLASH_PGM state while the operation is performed.*/ + devp->state = FLASH_ERASE; + + /* Clearing error status bits.*/ + sn32_flash_clear_status(devp); + + /* Enable page erase.*/ + devp->flash->CTRL = SN32_FLASH_CTRL_PER; + + /* Set the page.*/ + devp->flash->ADDR = (uint32_t)(efl_lld_descriptor.address + + flashGetSectorOffset(getBaseFlash(devp), sector)); + sn32_flash_wait_busy(devp); + + /* Start the erase.*/ + sn32_flash_start_pgm(devp); + sn32_flash_wait_busy(devp); + return FLASH_NO_ERROR; +} + +/** + * @brief Queries the driver for erase operation progress. + * + * @param[in] ip pointer to a @p EFlashDriver instance + * @param[out] msec recommended time, in milliseconds, that + * should be spent before calling this + * function again, can be @p NULL + * @return An error code. + * @retval FLASH_NO_ERROR if there is no erase operation in progress. + * @retval FLASH_BUSY_ERASING if there is an erase operation in progress. + * @retval FLASH_ERROR_ERASE if the erase operation failed. + * @retval FLASH_ERROR_HW_FAILURE if access to the memory failed. + * + * @api + */ +flash_error_t efl_lld_query_erase(void *instance, uint32_t *msec) { + EFlashDriver *devp = (EFlashDriver *)instance; + flash_error_t err = FLASH_NO_ERROR; + + /* If there is an erase in progress then the device must be checked.*/ + if (devp->state == FLASH_ERASE) { + + /* Checking for operation in progress.*/ + if ((devp->flash->STATUS & SN32_FLASH_STATUS_BUSY) == 0U) { + + /* Disabling the various erase control bits.*/ + devp->flash->CTRL &= ~(SN32_FLASH_CTRL_PER | SN32_FLASH_CTRL_MER); + + /* Back to ready state.*/ + devp->state = FLASH_READY; + } + else { + /* Recommended time before polling again. This is a simplified + implementation.*/ + if (msec != NULL) { + *msec = (uint32_t)SN32_FLASH_WAIT_TIME_MS; + } + + err = FLASH_BUSY_ERASING; + } + } + + return err; +} + +/** + * @brief Returns the erase state of a sector. + * + * @param[in] ip pointer to a @p EFlashDriver instance + * @param[in] sector sector to be verified + * @return An error code. + * @retval FLASH_NO_ERROR if the sector is erased. + * @retval FLASH_BUSY_ERASING if there is an erase operation in progress. + * @retval FLASH_ERROR_VERIFY if the verify operation failed. + * @retval FLASH_ERROR_HW_FAILURE if access to the memory failed. + * + * @notapi + */ +flash_error_t efl_lld_verify_erase(void *instance, flash_sector_t sector) { + EFlashDriver *devp = (EFlashDriver *)instance; + uint32_t *address; + flash_error_t err = FLASH_NO_ERROR; + unsigned i; + + osalDbgCheck(instance != NULL); + osalDbgCheck(sector < efl_lld_descriptor.sectors_count); + osalDbgAssert((devp->state == FLASH_READY) || (devp->state == FLASH_ERASE), + "invalid state"); + + /* No verifying while erasing.*/ + if (devp->state == FLASH_ERASE) { + return FLASH_BUSY_ERASING; + } + + /* Address of the sector.*/ + address = (uint32_t *)(SN32_FLASH_BASE + + flashGetSectorOffset(getBaseFlash(devp), sector)); + + /* FLASH_READ state while the operation is performed.*/ + devp->state = FLASH_READ; + + /* Scanning the sector space.*/ + uint32_t sector_size = flashGetSectorSize(getBaseFlash(devp), sector); + for (i = 0U; i < sector_size / sizeof(uint32_t); i++) { + if (*address != 0x00000000U) { + err = FLASH_ERROR_VERIFY; + break; + } + address++; + } + + /* Ready state again.*/ + devp->state = FLASH_READY; + + return err; +} + +#endif /* HAL_USE_EFL == TRUE */ + +/** @} */ diff --git a/os/hal/ports/SN32/SN32F260/hal_efl_lld.h b/os/hal/ports/SN32/SN32F260/hal_efl_lld.h new file mode 100644 index 0000000000..348ba983c1 --- /dev/null +++ b/os/hal/ports/SN32/SN32F260/hal_efl_lld.h @@ -0,0 +1,129 @@ +/* + ChibiOS - Copyright (C) 2006..2023 Giovanni Di Sirio + Copyright (C) 2023 Dimitris Mantzouranis + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +*/ + +/** + * @file hal_efl_lld.h + * @brief SN32F24xB Embedded Flash subsystem low level driver header. + * + * @addtogroup HAL_EFL + * @{ + */ + +#ifndef HAL_EFL_LLD_H +#define HAL_EFL_LLD_H + +#if (HAL_USE_EFL == TRUE) || defined(__DOXYGEN__) + +/*===========================================================================*/ +/* Driver constants. */ +/*===========================================================================*/ +#define SN32_FLASH_CTRL_PG 0x00000001 +#define SN32_FLASH_CTRL_PER 0x00000002 +#define SN32_FLASH_CTRL_MER 0x00000004 +#define SN32_FLASH_CTRL_START 0x00000040 +#define SN32_FLASH_CTRL_CHK 0x00000080 + +#define SN32_FLASH_STATUS_BUSY 0x00000001 +#define SN32_FLASH_STATUS_ERROR 0x00000004 + +/*===========================================================================*/ +/* Driver pre-compile time settings. */ +/*===========================================================================*/ + +/** + * @name SN32F24xB configuration options + * @{ + */ +/** + * @brief Suggested wait time during erase operations polling. + */ +#if !defined(SN32_FLASH_WAIT_TIME_MS) || defined(__DOXYGEN__) +#define SN32_FLASH_WAIT_TIME_MS 1 +#endif +/** @} */ + +/*===========================================================================*/ +/* Derived constants and error checks. */ +/*===========================================================================*/ + +#if !defined(SN32_FLASH_SECTOR_SIZE) +#error "SN32_FLASH_SECTOR_SIZE not defined in registry" +#endif + +#if !defined(SN32_FLASH_NUMBER_OF_BANKS) +#error "SN32_FLASH_NUMBER_OF_BANKS not defined in registry" +#endif + +#if !defined(SN32_FLASH_SECTORS_PER_BANK) +#error "SN32_FLASH_SECTORS_PER_BANK not defined in registry" +#endif + +/*===========================================================================*/ +/* Driver data structures and types. */ +/*===========================================================================*/ + +/*===========================================================================*/ +/* Driver macros. */ +/*===========================================================================*/ + +/** + * @brief Low level fields of the embedded flash driver structure. + */ +#define efl_lld_driver_fields \ + /* Flash registers.*/ \ + SN_FLASH_Type *flash + +/** + * @brief Low level fields of the embedded flash configuration structure. + */ +#define efl_lld_config_fields \ + /* Dummy configuration, it is not needed.*/ \ + uint32_t dummy + +/*===========================================================================*/ +/* External declarations. */ +/*===========================================================================*/ + +#if !defined(__DOXYGEN__) +extern EFlashDriver EFLD1; +#endif + +#ifdef __cplusplus +extern "C" { +#endif + void efl_lld_init(void); + void efl_lld_start(EFlashDriver *eflp); + void efl_lld_stop(EFlashDriver *eflp); + const flash_descriptor_t *efl_lld_get_descriptor(void *instance); + flash_error_t efl_lld_read(void *instance, flash_offset_t offset, + size_t n, uint8_t *rp); + flash_error_t efl_lld_program(void *instance, flash_offset_t offset, + size_t n, const uint8_t *pp); + flash_error_t efl_lld_start_erase_all(void *instance); + flash_error_t efl_lld_start_erase_sector(void *instance, + flash_sector_t sector); + flash_error_t efl_lld_query_erase(void *instance, uint32_t *wait_time); + flash_error_t efl_lld_verify_erase(void *instance, flash_sector_t sector); +#ifdef __cplusplus +} +#endif + +#endif /* HAL_USE_EFL == TRUE */ + +#endif /* HAL_EFL_LLD_H */ + +/** @} */ diff --git a/os/hal/ports/SN32/SN32F260/platform.mk b/os/hal/ports/SN32/SN32F260/platform.mk index e6ee0bd0f4..1b8774133b 100644 --- a/os/hal/ports/SN32/SN32F260/platform.mk +++ b/os/hal/ports/SN32/SN32F260/platform.mk @@ -1,6 +1,7 @@ # Required platform files. PLATFORMSRC_CONTRIB := $(CHIBIOS)/os/hal/ports/common/ARMCMx/nvic.c \ - $(CHIBIOS_CONTRIB)/os/hal/ports/SN32/SN32F260/hal_lld.c + $(CHIBIOS_CONTRIB)/os/hal/ports/SN32/SN32F260/hal_lld.c \ + $(CHIBIOS_CONTRIB)/os/hal/ports/SN32/SN32F260/hal_efl_lld.c # Required include directories. PLATFORMINC_CONTRIB := $(CHIBIOS)/os/hal/ports/common/ARMCMx \ @@ -22,7 +23,6 @@ endif include ${CHIBIOS_CONTRIB}/os/hal/ports/SN32/LLD/SN32F2xx/GPIO/driver.mk include ${CHIBIOS_CONTRIB}/os/hal/ports/SN32/LLD/SN32F2xx/USB/driver.mk include ${CHIBIOS_CONTRIB}/os/hal/ports/SN32/LLD/SN32F2xx/CT/driver.mk -include ${CHIBIOS_CONTRIB}/os/hal/ports/SN32/LLD/SN32F2xx/FLASH/driver.mk include ${CHIBIOS_CONTRIB}/os/hal/ports/SN32/LLD/SN32F2xx/SysTick/driver.mk include ${CHIBIOS_CONTRIB}/os/hal/ports/SN32/LLD/SN32F2xx/SPI/driver.mk include ${CHIBIOS_CONTRIB}/os/hal/ports/SN32/LLD/SN32F2xx/I2C/driver.mk diff --git a/os/hal/ports/SN32/SN32F260/sn32_registry.h b/os/hal/ports/SN32/SN32F260/sn32_registry.h index fe98310317..c80928be93 100644 --- a/os/hal/ports/SN32/SN32F260/sn32_registry.h +++ b/os/hal/ports/SN32/SN32F260/sn32_registry.h @@ -120,6 +120,16 @@ #define SN32_HAS_GPIOB TRUE #define SN32_HAS_GPIOA TRUE +/* + * FLASH units. + */ +#define SN32_JUMPLOADER_SIZE 0x200 +#define SN32_FLASH_LINE_SIZE 4U +#define SN32_FLASH_NUMBER_OF_BANKS 1 +#define SN32_FLASH_SECTORS_PER_BANK 480U +#define SN32_FLASH_SECTOR_SIZE 64U +#define SN32_FLASH_BASE 0x00000000UL +#define FLASH_SIZE (SN32_FLASH_NUMBER_OF_BANKS * SN32_FLASH_SECTORS_PER_BANK * SN32_FLASH_SECTOR_SIZE) /** @} */ #endif /* SN32_REGISTRY_H */