From b24866225a6301d3a663f874725e83c012dc25d3 Mon Sep 17 00:00:00 2001 From: Florent Duchon Date: Wed, 26 Dec 2012 17:36:00 +0100 Subject: digital/beacon: add bitcloud stack into common directory digital/zigbit --- .../stack/Components/HAL/drivers/OFD/Makefile | 107 +++ .../HAL/drivers/OFD/include/ofdMemoryDriver.h | 310 +++++++++ .../Components/HAL/drivers/OFD/src/ofdAt25Driver.c | 742 ++++++++++++++++++++ .../HAL/drivers/OFD/src/ofdAt45dbDriver.c | 758 +++++++++++++++++++++ .../Components/HAL/drivers/OFD/src/ofdCommand.c | 243 +++++++ .../Components/HAL/drivers/OFD/src/ofdCrcService.c | 66 ++ .../Components/HAL/drivers/OFD/src/ofdFakeDriver.c | 218 ++++++ .../HAL/drivers/OFD/src/ofdIntFlashRead.s | 40 ++ .../HAL/drivers/OFD/src/ofdIntFlashRead.s90 | 40 ++ .../HAL/drivers/OFD/src/ofdSpiSerializer.c | 91 +++ 10 files changed, 2615 insertions(+) create mode 100644 digital/zigbit/bitcloud/stack/Components/HAL/drivers/OFD/Makefile create mode 100644 digital/zigbit/bitcloud/stack/Components/HAL/drivers/OFD/include/ofdMemoryDriver.h create mode 100644 digital/zigbit/bitcloud/stack/Components/HAL/drivers/OFD/src/ofdAt25Driver.c create mode 100644 digital/zigbit/bitcloud/stack/Components/HAL/drivers/OFD/src/ofdAt45dbDriver.c create mode 100644 digital/zigbit/bitcloud/stack/Components/HAL/drivers/OFD/src/ofdCommand.c create mode 100644 digital/zigbit/bitcloud/stack/Components/HAL/drivers/OFD/src/ofdCrcService.c create mode 100644 digital/zigbit/bitcloud/stack/Components/HAL/drivers/OFD/src/ofdFakeDriver.c create mode 100644 digital/zigbit/bitcloud/stack/Components/HAL/drivers/OFD/src/ofdIntFlashRead.s create mode 100644 digital/zigbit/bitcloud/stack/Components/HAL/drivers/OFD/src/ofdIntFlashRead.s90 create mode 100644 digital/zigbit/bitcloud/stack/Components/HAL/drivers/OFD/src/ofdSpiSerializer.c (limited to 'digital/zigbit/bitcloud/stack/Components/HAL/drivers/OFD') diff --git a/digital/zigbit/bitcloud/stack/Components/HAL/drivers/OFD/Makefile b/digital/zigbit/bitcloud/stack/Components/HAL/drivers/OFD/Makefile new file mode 100644 index 00000000..ef22558f --- /dev/null +++ b/digital/zigbit/bitcloud/stack/Components/HAL/drivers/OFD/Makefile @@ -0,0 +1,107 @@ +COMPONENTS_PATH = ../../.. +#include $(COMPONENTS_PATH)/Makerules +include $(MAKERULES) + +DEBUG = NO +###### Option to switch on the fake driver ########## +ifndef APP_USE_FAKE_OFD_DRIVER + APP_USE_FAKE_OFD_DRIVER = 0 +endif + +# Hardware flags. +CFLAGS += $(CFLAGS_HW) + +##### PATHS FLAGS OF INCLUDES ######### +CFLAGS += -I./include +CFLAGS += -I./../include +CFLAGS += -I$(HAL_PATH)/include +CFLAGS += -I$(HAL_HWD_COMMON_PATH)/include +CFLAGS += -I$(SE_PATH)/include + +ifeq ($(DEBUG), YES) + CFLAGS += -D_DEBUG_ +endif + +#### ASM DEFINES FLAGS ####### +ifeq ($(COMPILER_TYPE), GCC) + ASMFLAGS = $(filter -mmcu%,$(CFLAGS)) + ASM_FILE_EXT = s +endif +ifeq ($(COMPILER_TYPE), IAR) + ASMFLAGS = -s+ # Enables case sensitivity. + ASMFLAGS += -w+ # Enables warnings. + ASMFLAGS += -M'<>'# Change asm.macro argument quote chars. + ASMFLAGS += -t8 # Set tab spacing. + ASMFLAGS += -u_enhancedCore + ASMFLAGS += -D__HAS_ENHANCED_CORE__=1 + ASMFLAGS += -D__HAS_MUL__=1 + ASMFLAGS += -D__MEMORY_MODEL__=2 + ifneq (, $(findstring $(HAL), ATMEGA1281 ATMEGA1284 AT90USB1287 ATMEGA128RFA1)) + ASMFLAGS += -v3 # Select processor option: Relative jumps do not wrap. + endif + ifneq (, $(findstring $(HAL), ATMEGA2561 ATXMEGA256A3 ATXMEGA256D3)) + ASMFLAGS += -v5 # Select processor option: Relative jumps do not wrap. + endif + ifneq (, $(findstring $(HAL), ATXMEGA256A3 ATXMEGA256D3)) + ASMFLAGS += --xmega #Enable Xmega specific instructions + endif + ASMFLAGS += -D__HAS_ELPM__=1 + ASMFLAGS += -S + ASM_FILE_EXT = s90 +endif + +###### LIB ########## +BUILDDIR = . + +LIBDIR = ./../lib +LDFLAGS = -L$(LIBDIR) +PROG = OFD.elf +LIBS = $(LIBDIR)/lib$(OFD_LIB).a + +driver_label: + @echo + @echo ---------------------------------------------------- + @echo Otau flash driver library creation. + @echo ---------------------------------------------------- + +ifneq ($(APP_USE_FAKE_OFD_DRIVER), 1) +modules = \ + ofdAt25fDriver \ + ofdAt45dbDriver \ + ofdCommand \ + ofdCrcService \ + ofdSpiSerializer + +asm_modules = \ + ofdIntFlashRead +else +modules = \ + ofdFakeDriver +endif + +objects = $(addsuffix .o,$(addprefix $(BUILDDIR)/objs/,$(modules))) +sources = $(addsuffix .c,$(addprefix $(BUILDDIR)/src/,$(modules))) +objects_asm = $(addsuffix .o,$(addprefix $(BUILDDIR)/objs/,$(asm_modules))) +sources_asm = $(addsuffix .$(ASM_FILE_EXT),$(addprefix $(BUILDDIR)/src/,$(asm_modules))) + +###### TARGETS ################ +all: driver_label LIB_OFD + +################ c part ###################### +$(BUILDDIR)/objs/%.o: $(BUILDDIR)/src/%.c + $(CC) $(CFLAGS) $^ -o $@ + +################ assembler part ###################### +$(BUILDDIR)/objs/%.o: $(BUILDDIR)/src/%.$(ASM_FILE_EXT) + $(AS) $(ASMFLAGS) -o $@ $^ + +################ +LIB_OFD : $(objects) $(objects_asm) + $(AR) $(AR_KEYS) $(LIBDIR)/lib$(OFD_LIB).a $(objects) $(objects_asm) + $(SIZE) -td $(LIBDIR)/lib$(OFD_LIB).a +################ +clean: + @echo ---------------------------------------------------- + @echo OTAU flash driver cleaning. + @echo ---------------------------------------------------- + rm -f $(objects) $(objects_asm) $(LIBS) $(BUILDDIR)/list/*.* \ No newline at end of file diff --git a/digital/zigbit/bitcloud/stack/Components/HAL/drivers/OFD/include/ofdMemoryDriver.h b/digital/zigbit/bitcloud/stack/Components/HAL/drivers/OFD/include/ofdMemoryDriver.h new file mode 100644 index 00000000..d158af26 --- /dev/null +++ b/digital/zigbit/bitcloud/stack/Components/HAL/drivers/OFD/include/ofdMemoryDriver.h @@ -0,0 +1,310 @@ +/**************************************************************************//** +\file ofdMemoryDriver.h + +\brief The implementation interface of external flash. + +\author + Atmel Corporation: http://www.atmel.com \n + Support email: avr@atmel.com + + Copyright (c) 2008-2011, Atmel Corporation. All rights reserved. + Licensed under Atmel's Limited License Agreement (BitCloudTM). + +\internal + History: + 31/07/09 A. Khromykh - Created +*******************************************************************************/ +/****************************************************************************** + * WARNING: CHANGING THIS FILE MAY AFFECT CORE FUNCTIONALITY OF THE STACK. * + * EXPERT USERS SHOULD PROCEED WITH CAUTION. * + ******************************************************************************/ +#ifndef _OFDMEMORYDRIVER_H +#define _OFDMEMORYDRIVER_H + +#ifdef _OTAU_ +/****************************************************************************** + Includes section +******************************************************************************/ +#include + +/****************************************************************************** + Define(s) section +******************************************************************************/ +#if EXTERNAL_MEMORY == AT25F2048 + + #if !defined(ATMEGA1281) && !defined(ATMEGA128RFA1) + #error 'at25f2048 is supported only for atmega1281/128rfa1.' + #endif + + // flash instruction format (see at25f2048 manual) + #define WREN 0x06 + #define WRDI 0x04 + #define RDSR 0x05 + #define WRSR 0x01 + #define READ 0x03 + #define PROGRAM 0x02 + #define SECTOR_ERASE 0x52 + #define CHIP_ERASE 0x62 + #define RDID 0x15 + + // status register bits + #define RDY 0x01 + #define WEN 0x02 + #define BP0 0x04 + #define BP1 0x08 + #define WPEN 0x80 + + // Atmel ID + #define OFD_MANUFACTURER_ID 0x1F + // at25f2048 + #define OFD_DEVICE_ID 0x63 + + #define PAGE_SIZE 256 + + // flash sectors + #define SECTOR_ONE 0x00000000ul + #define SECTOR_TWO 0x00010000ul + #define SECTOR_THREE 0x00020000ul + #define SECTOR_FOUR 0x00030000ul + // 2 Mbits + #define OFD_FLASH_SIZE 262144 + // image consists mcu flash - bootloader size + eeprom size. 128k - 4k + 4k + #define OFD_IMAGE_SIZE 131072 + #define OFD_FLASH_START_ADDRESS 0 + #define OFD_IMAGE1_START_ADDRESS OFD_FLASH_START_ADDRESS + #define OFD_IMAGE2_START_ADDRESS (OFD_FLASH_START_ADDRESS + OFD_IMAGE_SIZE) + + #define OFD_MCU_FLASH_SIZE OFD_IMAGE_SIZE + #define OFD_MCU_EEPROM_SIZE 4096 + #define OFD_EEPROM_OFFSET_WITHIN_IMAGE (OFD_MCU_FLASH_SIZE - OFD_MCU_EEPROM_SIZE) + // 1 byte (action for bootloader), 2 bytes (images crc), 1 byte table of image types. + #define OFD_SERVICE_INFO_SIZE 4 + +#elif EXTERNAL_MEMORY == AT45DB041 + + #if !defined(ATMEGA1281) && !defined(ATMEGA128RFA1) && !defined(ATXMEGA256A3) && !defined(ATXMEGA256D3) + #error 'at45db041 is supported only for atmega1281/128rfa1, atxmega256a/d3.' + #endif + + // flash instruction format (see at45db041 manual) + #define WRITE_BUF1 0x84 + #define WRITE_BUF2 0x87 + #define RDSR 0xD7 + #define READ 0xE8 + #define PROGRAM_BUF1 0x88 + #define PROGRAM_BUF2 0x89 + #define BLOCK_ERASE 0x50 + + // status register bits + #define RDY 0x80 + // unchanged bit mask within status register xx0111xx + #define STATUS_UNCHANGED_BIT_MASK 0x3C + #define STATUS_UNCHANGED_BITS 0x1C + + #define PAGE_SIZE 264 + // block addresses + #define FIRST_HALF_BLOCK_NUMBER 0 + #define SECOND_HALF_BLOCK_NUMBER 128 + + // 4 Mbits + #define OFD_FLASH_SIZE 540672 + + #if defined(ATMEGA1281) || defined(ATMEGA128RFA1) + // image consists mcu flash - bootloader size + eeprom size. 128k - 4k + 4k + // image uses 497 pages. 1 block = 8 pages + #define OFD_USED_BLOCKS_AMOUNT 63 + #define OFD_IMAGE_SIZE 131072 + #define OFD_MCU_FLASH_SIZE OFD_IMAGE_SIZE + #define OFD_EEPROM_OFFSET_WITHIN_IMAGE (OFD_MCU_FLASH_SIZE - OFD_MCU_EEPROM_SIZE) + #define OFD_LOAD_NO_COMMAND_TO_NVM + #elif defined(ATXMEGA256A3) || defined(ATXMEGA256D3) + // image consists mcu flash + eeprom size. 256k + 4k + // image uses 1009 pages. 1 block = 8 pages + #define OFD_USED_BLOCKS_AMOUNT 128 + #define OFD_IMAGE_SIZE 266240 + #define OFD_MCU_FLASH_SIZE 262144 + #define OFD_EEPROM_OFFSET_WITHIN_IMAGE OFD_MCU_FLASH_SIZE + #define OFD_LOAD_NO_COMMAND_TO_NVM NVM.CMD = NVM_CMD_NO_OPERATION_gc + #endif + + #define OFD_FLASH_START_ADDRESS 0 + #define OFD_IMAGE1_START_ADDRESS OFD_FLASH_START_ADDRESS + #define OFD_IMAGE2_START_ADDRESS 270336 + + #define OFD_MCU_EEPROM_SIZE 4096 + // 1 byte (action for bootloader), 2 bytes (images crc), 1 byte table of image types. + #define OFD_SERVICE_INFO_SIZE 4 + +#elif EXTERNAL_MEMORY == AT25DF041A + + #if !defined(ATXMEGA256A3) && !defined(ATXMEGA256D3) + #error 'at25df041a is supported only for atxmega256a3.' + #endif + + // flash instruction format (see at25df041a manual) + #define WREN 0x06 + #define WRDI 0x04 + #define RDSR 0x05 + #define WRSR 0x01 + #define READ 0x03 + #define PROGRAM 0x02 + #define SECTOR_ERASE 0xD8 + #define CHIP_ERASE 0x60 + #define RDID 0x9F + #define PROTECT_SECTOR 0x36 + #define UNPROTECT_SECTOR 0x39 + + // status register arguments + #define GLOBAL_UNPROTECT 0x00 + #define GLOBAL_PROTECT 0x7F + + // status register bits + #define RDY 0x01 + #define WEN 0x02 + #define SWP0 0x04 + #define SWP1 0x08 + #define WPP 0x10 + #define EPE 0x20 + #define SPM 0x40 + #define WPRL 0x80 + + // Atmel ID + #define OFD_MANUFACTURER_ID 0x1F + // at25df041a + #define OFD_DEVICE_ID_1 0x44 + #define OFD_DEVICE_ID_2 0x01 + #define EXT_STRING_LENGTH 0x00 + + #define PAGE_SIZE 256 + + // flash sectors + #define SECTOR_ONE 0x00000000ul + #define SECTOR_TWO 0x00010000ul + #define SECTOR_THREE 0x00020000ul + #define SECTOR_FOUR 0x00030000ul + // 4 Mbits + #define OFD_FLASH_SIZE 524288 + // image consists mcu flash size + eeprom size. 256k + 4k + #define OFD_IMAGE_SIZE 266240 + #define OFD_FLASH_START_ADDRESS 0 + #define OFD_IMAGE1_START_ADDRESS OFD_FLASH_START_ADDRESS + // this is fake start address used for code compatibility + #define OFD_IMAGE2_START_ADDRESS (OFD_FLASH_START_ADDRESS + OFD_IMAGE_SIZE) + + #define OFD_MCU_FLASH_SIZE OFD_IMAGE_SIZE + #define OFD_MCU_EEPROM_SIZE 4096 + #define OFD_EEPROM_OFFSET_WITHIN_IMAGE (OFD_MCU_FLASH_SIZE - OFD_MCU_EEPROM_SIZE) + // 1 byte (action for bootloader), 2 bytes (images crc), 1 byte table of image types. + #define OFD_SERVICE_INFO_SIZE 4 + +#else + #error 'Unknown memory type.' +#endif + +#define OFD_START_EEPROM_SREC_ADDRESS 0x810000 +#define OFD_LITTLE_TO_BIG_ENDIAN(A) ((((uint32_t)A & 0xFFul) << 24) \ + | (((uint32_t)A & 0xFF00ul) << 8) \ + | (((uint32_t)A >> 8) & 0xFF00ul) \ + | (((uint32_t)A >> 24) & 0xFFul)) + + +typedef struct +{ + union + { + uint32_t flashOffset; + uint16_t eepromOffset; + }; + uint8_t *data; + uint32_t length; +} OfdInternalMemoryAccessParam_t; + +// image type table +typedef uint8_t OfdImageTable_t; + +/****************************************************************************** + Prototypes section +******************************************************************************/ +/**************************************************************************//** +\brief Starts image erasing in the external memory. +******************************************************************************/ +void ofdEraseImage(void); + +/**************************************************************************//** +\brief Writes data to the external memory. +******************************************************************************/ +void ofdWriteData(void); + +/**************************************************************************//** +\brief Checks image crc. +******************************************************************************/ +void ofdCheckCrc(void); + +/**************************************************************************//** +\brief Starts saving internal flash. +******************************************************************************/ +void ofdSaveCurrentFlashImage(void); + +/**************************************************************************//** +\brief Reads image crc from internal eeprom. +******************************************************************************/ +void ofdReadCrc(void); + +/**************************************************************************//** +\brief Counts crc current memory area. CRC-8. Polynom 0x31 x^8 + x^5 + x^4 + 1. + +\param[in] + crc - first crc state +\param[in] + pcBlock - pointer to the memory for crc counting +\param[in] + length - memory size + +\return + current area crc +******************************************************************************/ +uint8_t ofdCrc(uint8_t crc, uint8_t *pcBlock, uint8_t length); + +/**************************************************************************//** +\brief Finds storage space. +******************************************************************************/ +void ofdFindStorageSpace(void); + +/**************************************************************************//** +\brief Sets action for internal bootloader. +******************************************************************************/ +void ofdSetActionForBootloader(void); + +/**************************************************************************//** +\brief Flushs memory buffer to flash. +******************************************************************************/ +void ofdFlushData(void); + +#if EXTERNAL_MEMORY == AT25DF041A +/**************************************************************************//** +\brief Unprotects memory sectors for writing and erasing. +******************************************************************************/ +void ofdUnprotectMemorySectors(void); +#endif + +/****************************************************************************** + Inline static functions prototypes section. +******************************************************************************/ +// Macros for the EXT_MEM_CS pin manipulation. +#if defined(ATMEGA1281) + +HAL_ASSIGN_PIN(EXT_MEM_CS, F, 3); + +#elif defined(ATMEGA128RFA1) + +HAL_ASSIGN_PIN(EXT_MEM_CS, G, 5); + +#elif defined(ATXMEGA256A3) || defined(ATXMEGA256D3) + +HAL_ASSIGN_PIN(EXT_MEM_CS, D, 4); + +#endif + +#endif // _OTAU_ + +#endif /* _OFDMEMORYDRIVER_H */ diff --git a/digital/zigbit/bitcloud/stack/Components/HAL/drivers/OFD/src/ofdAt25Driver.c b/digital/zigbit/bitcloud/stack/Components/HAL/drivers/OFD/src/ofdAt25Driver.c new file mode 100644 index 00000000..4f470eb4 --- /dev/null +++ b/digital/zigbit/bitcloud/stack/Components/HAL/drivers/OFD/src/ofdAt25Driver.c @@ -0,0 +1,742 @@ +/**************************************************************************//** +\file ofdAt25fDriver.c + +\brief Implementation of chip-flash interface. + +\author + Atmel Corporation: http://www.atmel.com \n + Support email: avr@atmel.com + + Copyright (c) 2008-2011, Atmel Corporation. All rights reserved. + Licensed under Atmel's Limited License Agreement (BitCloudTM). + +\internal + History: + 5/12/07 A. Khromykh - Created +*******************************************************************************/ +/****************************************************************************** + * WARNING: CHANGING THIS FILE MAY AFFECT CORE FUNCTIONALITY OF THE STACK. * + * EXPERT USERS SHOULD PROCEED WITH CAUTION. * + ******************************************************************************/ + +#ifdef _OTAU_ +#if ((EXTERNAL_MEMORY == AT25F2048) ||(EXTERNAL_MEMORY == AT25DF041A)) && (APP_USE_OTAU == 1) +#if APP_USE_FAKE_OFD_DRIVER == 0 + +/****************************************************************************** + Includes section +******************************************************************************/ +#include +#include +#include +#include +#include + +/****************************************************************************** + Define(s) section +******************************************************************************/ +#define SPI_BUSY_POLL_PERIOD 10 +// cycles of counting flash crc before context gap. +#define ATOMIC_COUNTING 128 +#define EEPROM_OK 0 +#define EEPROM_BUSY -2 + +/****************************************************************************** + Types section +******************************************************************************/ +typedef enum +{ + FLASH_BUSY, + FLASH_READY +} FlashBusyState_t; + +typedef enum +{ + FLASH_TRANSACTION, + EEPROM_TRANSACTION +} DelayedTransactionType_t; + +/****************************************************************************** + Prototypes section +******************************************************************************/ +static inline uint8_t ofdReadStatusRegister(void); +static inline void ofdStartPollTimer(DelayedTransactionType_t type); +static void ofdReadImageTable(void); +static void ofdSaveCrcCallback(void); +static void ofdContinueEraseImage(void); +static void ofdSaveCurrentEepromImage(void); +static void ofdFlushCrcCallback(OFD_Status_t status, OFD_ImageInfo_t *pInfo); +static void ofdSaveCurrentEepromImageContinue(void); +static void ofdPollBusyState(void); +static void ofdStartFlashDelayedTransaction(void); +static void ofdStartEepromDelayedTransaction(void); +uint8_t ofdReadInternalFlash(uint32_t flashAddress); +#if defined(_OFD_DEBUG_) +void ofdReadData(uint32_t address, uint8_t *data, uint16_t size, OFD_Callback_t cb); +#endif + +/****************************************************************************** + External variables section +******************************************************************************/ +extern HAL_SpiDescriptor_t spiDesc; +extern OFD_Position_t sectorNumber; +extern OFD_Position_t actionSector; +extern OFD_Callback_t ofdCallback; +extern OFD_Callback_t ofdAuxCallback; +extern OFD_MemoryAccessParam_t localAccessStructure; +extern OFD_ImageInfo_t imageInfo; +extern OfdImageTable_t imageTable; +extern OfdInternalMemoryAccessParam_t internalAccessParam; + +/****************************************************************************** + Global variables section +******************************************************************************/ +static HAL_AppTimer_t ofdBusyTimer = +{ + .interval = SPI_BUSY_POLL_PERIOD, + .mode = TIMER_ONE_SHOT_MODE, +}; +void (* delayedTransaction)(void) = NULL; +#if defined(_OFD_DEBUG_) +static HAL_UsartDescriptor_t usartDescriptor; +static uint32_t debugOffset = 0ul; +static uint8_t debugBuffer[OFD_BLOCK_SIZE]; +#endif + +/****************************************************************************** + Implementations section +******************************************************************************/ +/**************************************************************************//** +\brief Checks flash station. + +\return flash states: \n + FLASH_BUSY \n + FLASH_READY +******************************************************************************/ +static inline FlashBusyState_t ofdCheckBusyState(void) +{ + uint8_t statusReg = ofdReadStatusRegister(); + + if (!(statusReg & RDY)) + return FLASH_READY; + + return FLASH_BUSY; +} + +/**************************************************************************//** +\brief Starts flash delayed transaction. +******************************************************************************/ +static void ofdStartFlashDelayedTransaction(void) +{ + if (FLASH_READY == ofdCheckBusyState()) + delayedTransaction(); + else + ofdStartPollTimer(FLASH_TRANSACTION); +} + +/**************************************************************************//** +\brief Starts eeprom delayed transaction. +******************************************************************************/ +static void ofdStartEepromDelayedTransaction(void) +{ + if (!HAL_IsEepromBusy()) + delayedTransaction(); + else + ofdStartPollTimer(EEPROM_TRANSACTION); +} + +/**************************************************************************//** +\brief Starts timer for start delayed transaction. + +\param[in] + type - transaction type (flash or eeprom) +******************************************************************************/ +static inline void ofdStartPollTimer(DelayedTransactionType_t type) +{ + if (FLASH_TRANSACTION == type) + ofdBusyTimer.callback = ofdStartFlashDelayedTransaction; + else + ofdBusyTimer.callback = ofdStartEepromDelayedTransaction; + + HAL_StartAppTimer(&ofdBusyTimer); +} + +/**************************************************************************//** +\brief Routine of eeprom access. +\param[in] + result - result of hal eeprom action +\param[in] + action - initiator action +\return + false - incorrect parameters + true - eeprom transaction is started +******************************************************************************/ +static bool ofdEepromHandler(int result, void(* action)()) +{ + switch (result) + { + case EEPROM_OK: + return true; + case EEPROM_BUSY: + delayedTransaction = action; + ofdStartPollTimer(EEPROM_TRANSACTION); + return true; + default: + return false; + } +} + +/**************************************************************************//** +\brief Returns SUCCESS status. +******************************************************************************/ +static void ofdReturnSuccessStatus(void) +{ + if (ofdCallback) + ofdCallback(OFD_STATUS_SUCCESS); +} + +/**************************************************************************//** +\brief Reads image table. +******************************************************************************/ +static void ofdReadImageTable(void) +{ + HAL_EepromParams_t params; + + params.address = OFD_SERVICE_INFO_SIZE - sizeof(OfdImageTable_t); + params.data = &imageTable; + params.length = sizeof(OfdImageTable_t); + + if (!ofdEepromHandler(HAL_ReadEeprom(¶ms, ofdReturnSuccessStatus), ofdReadImageTable)) + if (ofdCallback) + ofdCallback(OFD_STATUS_INCORRECT_EEPROM_PARAMETER); +} + +/**************************************************************************//** +\brief Reads manufacturer ID and chip ID. +******************************************************************************/ +void ofdFindStorageSpace(void) +{ + uint64_t manufacId = RDID; + + if (FLASH_BUSY == ofdCheckBusyState()) + { // waits till flash ready + delayedTransaction = ofdFindStorageSpace; + ofdStartPollTimer(FLASH_TRANSACTION); + return; + } + + GPIO_EXT_MEM_CS_clr(); +#if EXTERNAL_MEMORY == AT25F2048 + HAL_ReadSpi(&spiDesc, (uint8_t *)&manufacId, sizeof(uint32_t)-1); +#elif EXTERNAL_MEMORY == AT25DF041A + HAL_ReadSpi(&spiDesc, (uint8_t *)&manufacId, sizeof(uint64_t)-3); +#endif + GPIO_EXT_MEM_CS_set(); + + if (OFD_MANUFACTURER_ID == (uint8_t)(manufacId >> 8)) + { +#if EXTERNAL_MEMORY == AT25F2048 + if (OFD_DEVICE_ID == (uint8_t)(manufacId >> 16)) +#elif EXTERNAL_MEMORY == AT25DF041A + if ((OFD_DEVICE_ID_1 == (uint8_t)(manufacId >> 16)) && + (OFD_DEVICE_ID_2 == (uint8_t)(manufacId >> 24)) && + (EXT_STRING_LENGTH == (uint8_t)(manufacId >> 32))) +#endif + { + // read image table to global variable + ofdReadImageTable(); + return; + } + } + + if (ofdCallback) + ofdCallback(OFD_STATUS_UNKNOWN_EXTERNAL_FLASH_TYPE); +} + +/**************************************************************************//** +\brief Reads status register from the external flash. + +\return status register +******************************************************************************/ +static inline uint8_t ofdReadStatusRegister(void) +{ + uint16_t regStatus = RDSR; + + GPIO_EXT_MEM_CS_clr(); + HAL_ReadSpi(&spiDesc, (uint8_t *)®Status, sizeof(uint16_t)); + GPIO_EXT_MEM_CS_set(); + + return (uint8_t)(regStatus >> 8); +} + +/**************************************************************************//** +\brief Sends "write enable" command to the external flash. +******************************************************************************/ +void ofdSendWriteEnable(void) +{ + uint8_t wren = WREN; + + GPIO_EXT_MEM_CS_clr(); + HAL_WriteSpi(&spiDesc, &wren, sizeof(uint8_t)); + GPIO_EXT_MEM_CS_set(); +} + +/**************************************************************************//** +\brief Starts physical sector erasing in the external memory. + +\param[in] + sectorNumber - address from erased sector +******************************************************************************/ +void ofdEraseSector(uint32_t sectorNumber) +{ + uint32_t erasedSector = sectorNumber | ((uint32_t)SECTOR_ERASE << 24); + + ofdSendWriteEnable(); + erasedSector = OFD_LITTLE_TO_BIG_ENDIAN(erasedSector); + GPIO_EXT_MEM_CS_clr(); + HAL_WriteSpi(&spiDesc, (uint8_t *)&erasedSector, sizeof(uint32_t)); + GPIO_EXT_MEM_CS_set(); +} + +/**************************************************************************//** +\brief Starts image erasing in the external memory. +******************************************************************************/ +void ofdEraseImage(void) +{ + if (FLASH_BUSY == ofdCheckBusyState()) + { // waits till flash ready + delayedTransaction = ofdEraseImage; + ofdStartPollTimer(FLASH_TRANSACTION); + return; + } + + if (OFD_POSITION_1 == sectorNumber) + ofdEraseSector(SECTOR_ONE); + else + ofdEraseSector(SECTOR_THREE); + + delayedTransaction = ofdContinueEraseImage; + ofdStartPollTimer(FLASH_TRANSACTION); +} + +/**************************************************************************//** +\brief Continues image erasing in the external memory. +******************************************************************************/ +static void ofdContinueEraseImage(void) +{ + if (OFD_POSITION_1 == sectorNumber) + ofdEraseSector(SECTOR_TWO); + else + ofdEraseSector(SECTOR_FOUR); + + ofdReturnSuccessStatus(); +} + +/**************************************************************************//** +\brief Writes data to the external memory. +******************************************************************************/ +void ofdWriteData(void) +{ + uint8_t *dataPointer; + uint16_t dataLength; + uint32_t dataAddress; + uint8_t writeInstruc = PROGRAM; + + if (!localAccessStructure.length) + { + ofdReturnSuccessStatus(); + return; + } + + if (FLASH_BUSY == ofdCheckBusyState()) + { // waits till flash ready + delayedTransaction = ofdWriteData; + ofdStartPollTimer(FLASH_TRANSACTION); + return; + } + + dataAddress = OFD_LITTLE_TO_BIG_ENDIAN(localAccessStructure.offset); + dataAddress >>= 8; + dataPointer = localAccessStructure.data; + dataLength = PAGE_SIZE - (uint8_t)localAccessStructure.offset; + if (dataLength >= localAccessStructure.length) + dataLength = localAccessStructure.length; + + localAccessStructure.data += dataLength; + localAccessStructure.offset += dataLength; + localAccessStructure.length -= dataLength; + + ofdSendWriteEnable(); + GPIO_EXT_MEM_CS_clr(); + HAL_WriteSpi(&spiDesc, &writeInstruc, sizeof(uint8_t)); + HAL_WriteSpi(&spiDesc, (uint8_t *)&dataAddress, sizeof(uint32_t)-1); + HAL_WriteSpi(&spiDesc, dataPointer, dataLength); + GPIO_EXT_MEM_CS_set(); + + delayedTransaction = ofdWriteData; + ofdStartPollTimer(FLASH_TRANSACTION); +} + +/**************************************************************************//** +\brief Calls callback about end of eeprom saving. +******************************************************************************/ +static void ofdSaveCrcCallback(void) +{ + if (ofdCallback) + ((OFD_InfoCallback_t)ofdCallback)(OFD_STATUS_SUCCESS, &imageInfo); +} + +/**************************************************************************//** +\brief Saves image table to the internal eeprom. +******************************************************************************/ +void ofdSaveImageTable(void) +{ + HAL_EepromParams_t params; + + params.address = OFD_SERVICE_INFO_SIZE-1; + params.data = &imageTable; + params.length = sizeof(OfdImageTable_t); + + if (!ofdEepromHandler(HAL_WriteEeprom(¶ms, ofdSaveCrcCallback), ofdSaveImageTable)) + if (ofdCallback) + ((OFD_InfoCallback_t)ofdCallback)(OFD_STATUS_INCORRECT_EEPROM_PARAMETER, &imageInfo); +} + +/**************************************************************************//** +\brief Saves crc to the internal eeprom. +******************************************************************************/ +void ofdSaveCrc(void) +{ + HAL_EepromParams_t params; + + params.address = sectorNumber + 1; + params.data = &imageInfo.crc; + params.length = sizeof(uint8_t); + + if (!ofdEepromHandler(HAL_WriteEeprom(¶ms, ofdSaveImageTable), ofdSaveCrc)) + if (ofdCallback) + ((OFD_InfoCallback_t)ofdCallback)(OFD_STATUS_INCORRECT_EEPROM_PARAMETER, &imageInfo); +} + +/**************************************************************************//** +\brief Flushs memory buffer to flash. +******************************************************************************/ +void ofdFlushData(void) +{} + +/**************************************************************************//** +\brief Checks image crc. +******************************************************************************/ +void ofdCheckCrc(void) +{ + uint32_t address; + uint8_t writeInstruc = READ; + uint8_t atomicCounting = ATOMIC_COUNTING; + + if (FLASH_BUSY == ofdCheckBusyState()) + { // waits till flash ready + delayedTransaction = ofdCheckCrc; + ofdStartPollTimer(FLASH_TRANSACTION); + return; + } + + while (atomicCounting--) + { + address = localAccessStructure.offset; + address = OFD_LITTLE_TO_BIG_ENDIAN(address<<8); + GPIO_EXT_MEM_CS_clr(); + HAL_WriteSpi(&spiDesc, &writeInstruc, sizeof(uint8_t)); + HAL_WriteSpi(&spiDesc, (uint8_t *)&address, sizeof(uint32_t)-1); + HAL_ReadSpi(&spiDesc, localAccessStructure.data, OFD_BLOCK_FOR_CHECK_CRC); + GPIO_EXT_MEM_CS_set(); // release spi cs + imageInfo.crc = ofdCrc(imageInfo.crc, localAccessStructure.data, OFD_BLOCK_FOR_CHECK_CRC); + localAccessStructure.offset += OFD_BLOCK_FOR_CHECK_CRC; + localAccessStructure.length -= OFD_BLOCK_FOR_CHECK_CRC; + if (!localAccessStructure.length) + { + ofdSaveCrc(); + return; + } + } + // context gap + delayedTransaction = ofdCheckCrc; + ofdStartPollTimer(FLASH_TRANSACTION); +} + +/**************************************************************************//** +\brief Callback for saving internal flash. + +\param[in] status - status of the data flash writing +******************************************************************************/ +void ofdWriteFlashDataCallback(OFD_Status_t status) +{ + uint32_t maxOffset; + + if (OFD_STATUS_SUCCESS != status) + { + if (ofdAuxCallback) + ofdAuxCallback(status); + return; + } + if (OFD_POSITION_1 == sectorNumber) + maxOffset = OFD_IMAGE1_START_ADDRESS + OFD_MCU_FLASH_SIZE - OFD_MCU_EEPROM_SIZE; + else + maxOffset = OFD_IMAGE2_START_ADDRESS + OFD_MCU_FLASH_SIZE - OFD_MCU_EEPROM_SIZE; + + if (localAccessStructure.offset < maxOffset) + { // save mcu flash + ofdSaveCurrentFlashImage(); + return; + } + + internalAccessParam.eepromOffset = 0; + // save eeprom image + ofdSaveCurrentEepromImage(); +} + +/**************************************************************************//** +\brief Starts saving internal flash. +******************************************************************************/ +void ofdSaveCurrentFlashImage(void) +{ +#if EXTERNAL_MEMORY == AT25F2048 + uint16_t itr; + + localAccessStructure.length = OFD_BLOCK_FOR_CHECK_CRC; + localAccessStructure.data = internalAccessParam.data; + for (itr = 0; itr < OFD_BLOCK_FOR_CHECK_CRC; itr++) + internalAccessParam.data[itr] = ofdReadInternalFlash(internalAccessParam.flashOffset++); + internalAccessParam.length -= OFD_BLOCK_FOR_CHECK_CRC; + ofdCallback = ofdWriteFlashDataCallback; + ofdWriteData(); +#elif EXTERNAL_MEMORY == AT25DF041A + ofdSetActionForBootloader(); +#endif +} + +/**************************************************************************//** +\brief Callback for saving internal eeprom. + +\param[in] status - status of the data eeprom writing +******************************************************************************/ +void ofdWriteEepromDataCallback(OFD_Status_t status) +{ + uint32_t maxOffset; + + if (OFD_STATUS_SUCCESS != status) + { + if (ofdAuxCallback) + ofdAuxCallback(status); + return; + } + if (OFD_POSITION_1 == sectorNumber) + maxOffset = OFD_IMAGE1_START_ADDRESS + OFD_MCU_FLASH_SIZE; + else + maxOffset = OFD_IMAGE2_START_ADDRESS + OFD_MCU_FLASH_SIZE; + + if (localAccessStructure.offset < maxOffset) + { // save mcu eeprom + ofdSaveCurrentEepromImage(); + return; + } + + // start check crc + OFD_FlushAndCheckCrc(sectorNumber, internalAccessParam.data, ofdFlushCrcCallback); +} + +/**************************************************************************//** +\brief Starts saving internal eeprom. +******************************************************************************/ +static void ofdSaveCurrentEepromImage(void) +{ + HAL_EepromParams_t params; + + params.address = internalAccessParam.eepromOffset; + params.data = internalAccessParam.data; + params.length = OFD_BLOCK_FOR_CHECK_CRC; + + if (!ofdEepromHandler(HAL_ReadEeprom(¶ms, ofdSaveCurrentEepromImageContinue), ofdSaveCurrentEepromImage)) + if (ofdAuxCallback) + ofdAuxCallback(OFD_STATUS_INCORRECT_EEPROM_PARAMETER); +} + +/**************************************************************************//** +\brief Continues saving internal flash. +******************************************************************************/ +static void ofdSaveCurrentEepromImageContinue(void) +{ + localAccessStructure.length = OFD_BLOCK_FOR_CHECK_CRC; + localAccessStructure.data = internalAccessParam.data; + if (0 == internalAccessParam.eepromOffset) + memset(internalAccessParam.data, 0xFF, OFD_SERVICE_INFO_SIZE); + + internalAccessParam.eepromOffset += OFD_BLOCK_FOR_CHECK_CRC; + internalAccessParam.length -= OFD_BLOCK_FOR_CHECK_CRC; + ofdCallback = ofdWriteEepromDataCallback; + ofdWriteData(); +} + +/**************************************************************************//** +\brief Callback for start of saving of action for bootloader. + +\param[in] + status - status of the crc saving to eeprom +\param[in] + pInfo - ponter to image information +******************************************************************************/ +static void ofdFlushCrcCallback(OFD_Status_t status, OFD_ImageInfo_t *pInfo) +{ + (void)pInfo; + + if (OFD_STATUS_SUCCESS != status) + { + if (ofdAuxCallback) + ofdAuxCallback(status); + return; + } + ofdSetActionForBootloader(); +} + +/**************************************************************************//** +\brief Sets action for internal bootloader. +******************************************************************************/ +void ofdSetActionForBootloader(void) +{ + HAL_EepromParams_t params; + + params.address = 0; + params.data = (uint8_t *)&actionSector; + params.length = sizeof(OFD_Position_t); + + if (!ofdEepromHandler(HAL_WriteEeprom(¶ms, ofdPollBusyState), ofdSetActionForBootloader)) + if (ofdAuxCallback) + ofdAuxCallback(OFD_STATUS_INCORRECT_EEPROM_PARAMETER); +} + +/**************************************************************************//** +\brief Waits for end of image saving. +******************************************************************************/ +static void ofdPollBusyState(void) +{ + if (FLASH_BUSY == ofdCheckBusyState()) + { // waits till flash ready + delayedTransaction = ofdPollBusyState; + ofdStartPollTimer(FLASH_TRANSACTION); + return; + } + + if (ofdAuxCallback) + ofdAuxCallback(OFD_STATUS_SUCCESS); +} + +/**************************************************************************//** +\brief Reads image crc from internal eeprom. +******************************************************************************/ +void ofdReadCrc(void) +{ + HAL_EepromParams_t params; + + params.address = sectorNumber + 1; + params.data = &imageInfo.crc; + params.length = sizeof(uint8_t); + + if (!ofdEepromHandler(HAL_ReadEeprom(¶ms, ofdSaveCrcCallback), ofdReadCrc)) + if (ofdCallback) + ((OFD_InfoCallback_t)ofdCallback)(OFD_STATUS_INCORRECT_EEPROM_PARAMETER, &imageInfo); +} + +#if EXTERNAL_MEMORY == AT25DF041A +/**************************************************************************//** +\brief Unprotects memory sectors for writing and erasing. +******************************************************************************/ +void ofdUnprotectMemorySectors(void) +{ + uint8_t unprotect = WRSR; + uint8_t unprotectArg = GLOBAL_UNPROTECT; + + ofdSendWriteEnable(); + GPIO_EXT_MEM_CS_clr(); + HAL_WriteSpi(&spiDesc, &unprotect, sizeof(uint8_t)); + HAL_WriteSpi(&spiDesc, &unprotectArg, sizeof(uint8_t)); + GPIO_EXT_MEM_CS_set(); +} +#endif + +#if defined(_OFD_DEBUG_) +/**************************************************************************//** +\brief Flash read callback. +******************************************************************************/ +void ofdReadConfirm(OFD_Status_t status) +{ + HAL_WriteUsart(&usartDescriptor, debugBuffer, OFD_BLOCK_SIZE); +} + +/**************************************************************************//** +\brief Usart write callback. +******************************************************************************/ +void usartWriteConfirm(void) +{ + debugOffset += OFD_BLOCK_SIZE; + if (debugOffset < OFD_IMAGE_SIZE) + { + ofdReadData(debugOffset, debugBuffer, OFD_BLOCK_SIZE, ofdReadConfirm); + } +} + +/**************************************************************************//** +\brief Initialization of usart for consinsting of flash transmitting. +******************************************************************************/ +void ofdInitDebugInterface(void) +{ + usartDescriptor.tty = USART_CHANNEL_1; + usartDescriptor.mode = USART_MODE_ASYNC; + usartDescriptor.flowControl = USART_FLOW_CONTROL_NONE; + usartDescriptor.baudrate = USART_BAUDRATE_38400; + usartDescriptor.dataLength = USART_DATA8; + usartDescriptor.parity = USART_PARITY_NONE; + usartDescriptor.stopbits = USART_STOPBIT_1; + usartDescriptor.rxBuffer = NULL; + usartDescriptor.rxBufferLength = 0; + usartDescriptor.txBuffer = NULL; + usartDescriptor.txBufferLength = 0; + usartDescriptor.rxCallback = NULL; + usartDescriptor.txCallback = usartWriteConfirm; + + HAL_OpenUsart(&usartDescriptor); + ofdReadData(debugOffset, debugBuffer, OFD_BLOCK_SIZE, ofdReadConfirm); +} + +/**************************************************************************//** +\brief Reads data from the external memory. + +\param[in] + address - flash cell address +\param[out] + data - pointer to memory buffer +\param[in] + size - size of memory buffer +\param[in] + cb - pointer to callback +******************************************************************************/ +void ofdReadData(uint32_t address, uint8_t *data, uint16_t size, OFD_Callback_t cb) +{ + uint8_t writeInstruc = READ; + + while (FLASH_BUSY == ofdCheckBusyState()) + {;}// waits till flash ready + + address = OFD_LITTLE_TO_BIG_ENDIAN(address<<8); + GPIO_EXT_MEM_CS_clr(); + HAL_WriteSpi(&spiDesc, &writeInstruc, sizeof(uint8_t)); + HAL_WriteSpi(&spiDesc, (uint8_t *)&address, sizeof(uint32_t)-1); + HAL_ReadSpi(&spiDesc, data, size); + GPIO_EXT_MEM_CS_set(); + if (cb) + cb(OFD_STATUS_SUCCESS); +} +#endif // defined(_OFD_DEBUG_) + +#endif // APP_USE_FAKE_OFD_DRIVER == 0 +#endif // ((EXTERNAL_MEMORY == AT25F2048) ||(EXTERNAL_MEMORY == AT25DF041A)) && (APP_USE_OTAU == 1) +#endif // _OTAU_ +// eof ofdAt25fDriver.c diff --git a/digital/zigbit/bitcloud/stack/Components/HAL/drivers/OFD/src/ofdAt45dbDriver.c b/digital/zigbit/bitcloud/stack/Components/HAL/drivers/OFD/src/ofdAt45dbDriver.c new file mode 100644 index 00000000..f06d765d --- /dev/null +++ b/digital/zigbit/bitcloud/stack/Components/HAL/drivers/OFD/src/ofdAt45dbDriver.c @@ -0,0 +1,758 @@ +/**************************************************************************//** +\file ofdAt45dbDriver.c + +\brief Implementation of chip-flash interface. + +\author + Atmel Corporation: http://www.atmel.com \n + Support email: avr@atmel.com + + Copyright (c) 2008-2011, Atmel Corporation. All rights reserved. + Licensed under Atmel's Limited License Agreement (BitCloudTM). + +\internal + History: + 20/07/10 A. Khromykh - Created +*******************************************************************************/ +/****************************************************************************** + * WARNING: CHANGING THIS FILE MAY AFFECT CORE FUNCTIONALITY OF THE STACK. * + * EXPERT USERS SHOULD PROCEED WITH CAUTION. * + ******************************************************************************/ + +#ifdef _OTAU_ +#if (EXTERNAL_MEMORY == AT45DB041) && (APP_USE_OTAU == 1) +#if APP_USE_FAKE_OFD_DRIVER == 0 + +/****************************************************************************** + Includes section +******************************************************************************/ +#include +#include +#include +#include +#include + +/****************************************************************************** + Define(s) section +******************************************************************************/ +#define SPI_BUSY_POLL_PERIOD 10 +// cycles of counting flash crc before context gap. +#define ATOMIC_COUNTING 128 +#define EEPROM_OK 0 +#define EEPROM_BUSY -2 +#define ALL_DATA_HAS_BEEN_SAVED 0xFFFFFFFFul + +/****************************************************************************** + Types section +******************************************************************************/ +typedef enum +{ + FLASH_BUSY, + FLASH_READY +} FlashBusyState_t; + +typedef enum +{ + FLASH_TRANSACTION, + EEPROM_TRANSACTION +} DelayedTransactionType_t; + +/****************************************************************************** + Prototypes section +******************************************************************************/ +static inline uint8_t ofdReadStatusRegister(void); +static inline void ofdStartPollTimer(DelayedTransactionType_t type); +static void ofdReadImageTable(void); +static void ofdSaveCrcCallback(void); +static void ofdSaveCurrentEepromImage(void); +static void ofdFlushCrcCallback(OFD_Status_t status, OFD_ImageInfo_t *pInfo); +static void ofdSaveCurrentEepromImageContinue(void); +static void ofdPollBusyState(void); +static void ofdStartFlashDelayedTransaction(void); +static void ofdStartEepromDelayedTransaction(void); +static void ofdClearFlashInternalBuffer(void); +uint8_t ofdReadInternalFlash(uint32_t flashAddress); +#if defined(_OFD_DEBUG_) +void ofdReadData(uint32_t address, uint8_t *data, uint16_t size, OFD_Callback_t cb); +#endif + +/****************************************************************************** + External variables section +******************************************************************************/ +extern HAL_SpiDescriptor_t spiDesc; +extern OFD_Position_t sectorNumber; +extern OFD_Position_t actionSector; +extern OFD_Callback_t ofdCallback; +extern OFD_Callback_t ofdAuxCallback; +extern OFD_MemoryAccessParam_t localAccessStructure; +extern OFD_ImageInfo_t imageInfo; +extern OfdImageTable_t imageTable; +extern OfdInternalMemoryAccessParam_t internalAccessParam; + +/****************************************************************************** + Global variables section +******************************************************************************/ +static HAL_AppTimer_t ofdBusyTimer = +{ + .interval = SPI_BUSY_POLL_PERIOD, + .mode = TIMER_ONE_SHOT_MODE, +}; +void (* delayedTransaction)(void) = NULL; +static uint16_t serviceGapData = 0; +static uint32_t flushedPageAddr = ALL_DATA_HAS_BEEN_SAVED; +#if defined(_OFD_DEBUG_) +static HAL_UsartDescriptor_t usartDescriptor; +static uint32_t debugOffset = 0ul; +static uint8_t debugBuffer[OFD_BLOCK_SIZE]; +#endif + +/****************************************************************************** + Implementations section +******************************************************************************/ +/**************************************************************************//** +\brief Checks flash state. + +\return flash states: \n + FLASH_BUSY \n + FLASH_READY +******************************************************************************/ +static inline FlashBusyState_t ofdCheckBusyState(void) +{ + uint8_t statusReg = ofdReadStatusRegister(); + + if (statusReg & RDY) + return FLASH_READY; + + return FLASH_BUSY; +} + +/**************************************************************************//** +\brief Starts flash delayed transaction. +******************************************************************************/ +static void ofdStartFlashDelayedTransaction(void) +{ + if (FLASH_READY == ofdCheckBusyState()) + delayedTransaction(); + else + ofdStartPollTimer(FLASH_TRANSACTION); +} + +/**************************************************************************//** +\brief Starts eeprom delayed transaction. +******************************************************************************/ +static void ofdStartEepromDelayedTransaction(void) +{ + if (!HAL_IsEepromBusy()) + delayedTransaction(); + else + ofdStartPollTimer(EEPROM_TRANSACTION); +} + +/**************************************************************************//** +\brief Starts timer for start delayed transaction. + +\param[in] + type - transaction type (flash or eeprom) +******************************************************************************/ +static inline void ofdStartPollTimer(DelayedTransactionType_t type) +{ + if (FLASH_TRANSACTION == type) + ofdBusyTimer.callback = ofdStartFlashDelayedTransaction; + else + ofdBusyTimer.callback = ofdStartEepromDelayedTransaction; + + HAL_StartAppTimer(&ofdBusyTimer); +} + +/**************************************************************************//** +\brief Routine of eeprom access. +\param[in] + result - result of hal eeprom action +\param[in] + action - initiator action +\return + false - incorrect parameters + true - eeprom transaction is started +******************************************************************************/ +static bool ofdEepromHandler(int result, void(* action)()) +{ + switch (result) + { + case EEPROM_OK: + return true; + case EEPROM_BUSY: + delayedTransaction = action; + ofdStartPollTimer(EEPROM_TRANSACTION); + return true; + default: + return false; + } +} + +/**************************************************************************//** +\brief Returns SUCCESS status. +******************************************************************************/ +static void ofdReturnSuccessStatus(void) +{ + if (ofdCallback) + ofdCallback(OFD_STATUS_SUCCESS); +} + +/**************************************************************************//** +\brief Reads image table. +******************************************************************************/ +static void ofdReadImageTable(void) +{ + HAL_EepromParams_t params; + + params.address = OFD_SERVICE_INFO_SIZE - sizeof(OfdImageTable_t); + params.data = &imageTable; + params.length = sizeof(OfdImageTable_t); + + if (!ofdEepromHandler(HAL_ReadEeprom(¶ms, ofdReturnSuccessStatus), ofdReadImageTable)) + if (ofdCallback) + ofdCallback(OFD_STATUS_INCORRECT_EEPROM_PARAMETER); +} + +/**************************************************************************//** +\brief Reads status register and check unchanged bits. +******************************************************************************/ +void ofdFindStorageSpace(void) +{ + if (STATUS_UNCHANGED_BITS == (ofdReadStatusRegister() & STATUS_UNCHANGED_BIT_MASK)) + { + // read image table to global variable + ofdReadImageTable(); + return; + } + + if (ofdCallback) + ofdCallback(OFD_STATUS_UNKNOWN_EXTERNAL_FLASH_TYPE); +} + +/**************************************************************************//** +\brief Reads status register from the external flash. + +\return status register +******************************************************************************/ +static inline uint8_t ofdReadStatusRegister(void) +{ + uint16_t regStatus = RDSR; + + GPIO_EXT_MEM_CS_clr(); + HAL_ReadSpi(&spiDesc, (uint8_t *)®Status, sizeof(uint16_t)); + GPIO_EXT_MEM_CS_set(); + + return (uint8_t)(regStatus >> 8); +} + +/**************************************************************************//** +\brief Starts physical block(8 pages) erasing in the external memory. + +\param[in] + blockNumber - address of the erased block +******************************************************************************/ +void ofdEraseBlock(uint8_t blockNumber) +{ + uint32_t erasedBlock = OFD_LITTLE_TO_BIG_ENDIAN((uint32_t)blockNumber << 4); + + erasedBlock >>= 8; + erasedBlock |= BLOCK_ERASE; + + GPIO_EXT_MEM_CS_clr(); + HAL_WriteSpi(&spiDesc, (uint8_t *)&erasedBlock, sizeof(uint32_t)); + GPIO_EXT_MEM_CS_set(); +} + +/**************************************************************************//** +\brief Starts image erasing in the external memory. +******************************************************************************/ +void ofdEraseImage(void) +{ + if (FLASH_BUSY == ofdCheckBusyState()) + { // waits till flash ready + delayedTransaction = ofdEraseImage; + ofdStartPollTimer(FLASH_TRANSACTION); + return; + } + + if (OFD_POSITION_1 == sectorNumber) + ofdEraseBlock(FIRST_HALF_BLOCK_NUMBER + serviceGapData++); + else + ofdEraseBlock(SECOND_HALF_BLOCK_NUMBER + serviceGapData++); + + if (serviceGapData < OFD_USED_BLOCKS_AMOUNT) + { + delayedTransaction = ofdEraseImage; + ofdStartPollTimer(FLASH_TRANSACTION); + } + else + { + serviceGapData = 0; + ofdReturnSuccessStatus(); + } +} + +/**************************************************************************//** +\brief Writes data to the external memory. +******************************************************************************/ +void ofdWriteData(void) +{ + uint8_t *dataPointer; + uint16_t dataLength; + uint32_t address; + uint32_t pageAddr; + uint32_t byteAddr; + + if (!localAccessStructure.length) + { + ofdReturnSuccessStatus(); + return; + } + + if (FLASH_BUSY == ofdCheckBusyState()) + { // waits till flash ready + delayedTransaction = ofdWriteData; + ofdStartPollTimer(FLASH_TRANSACTION); + return; + } + + pageAddr = localAccessStructure.offset / PAGE_SIZE; + + if ((pageAddr > flushedPageAddr) && (ALL_DATA_HAS_BEEN_SAVED != flushedPageAddr)) + { // there is gap in the image address map. + ofdFlushData(); + delayedTransaction = ofdClearFlashInternalBuffer; + ofdStartPollTimer(FLASH_TRANSACTION); + return; + } + + flushedPageAddr = pageAddr; + byteAddr = localAccessStructure.offset % PAGE_SIZE; + dataPointer = localAccessStructure.data; + + if ((byteAddr + localAccessStructure.length) > PAGE_SIZE) + dataLength = PAGE_SIZE - byteAddr; + else + dataLength = localAccessStructure.length; + + localAccessStructure.data += dataLength; + localAccessStructure.offset += dataLength; + localAccessStructure.length -= dataLength; + + address = OFD_LITTLE_TO_BIG_ENDIAN(byteAddr); + address |= WRITE_BUF1; + + GPIO_EXT_MEM_CS_clr(); + HAL_WriteSpi(&spiDesc, (uint8_t *)&address, sizeof(uint32_t)); + HAL_WriteSpi(&spiDesc, dataPointer, dataLength); + GPIO_EXT_MEM_CS_set(); + + if (PAGE_SIZE == (byteAddr + dataLength)) + { + ofdFlushData(); + delayedTransaction = ofdClearFlashInternalBuffer; + ofdStartPollTimer(FLASH_TRANSACTION); + return; + } + + ofdReturnSuccessStatus(); +} + +/**************************************************************************//** +\brief Calls callback about end of eeprom saving. +******************************************************************************/ +static void ofdSaveCrcCallback(void) +{ + if (ofdCallback) + ((OFD_InfoCallback_t)ofdCallback)(OFD_STATUS_SUCCESS, &imageInfo); +} + +/**************************************************************************//** +\brief Saves image table to the internal eeprom. +******************************************************************************/ +void ofdSaveImageTable(void) +{ + HAL_EepromParams_t params; + + params.address = OFD_SERVICE_INFO_SIZE-1; + params.data = &imageTable; + params.length = sizeof(OfdImageTable_t); + + if (!ofdEepromHandler(HAL_WriteEeprom(¶ms, ofdSaveCrcCallback), ofdSaveImageTable)) + if (ofdCallback) + ((OFD_InfoCallback_t)ofdCallback)(OFD_STATUS_INCORRECT_EEPROM_PARAMETER, &imageInfo); +} + +/**************************************************************************//** +\brief Saves crc to the internal eeprom. +******************************************************************************/ +void ofdSaveCrc(void) +{ + HAL_EepromParams_t params; + + params.address = sectorNumber + 1; + params.data = &imageInfo.crc; + params.length = sizeof(uint8_t); + + if (!ofdEepromHandler(HAL_WriteEeprom(¶ms, ofdSaveImageTable), ofdSaveCrc)) + if (ofdCallback) + ((OFD_InfoCallback_t)ofdCallback)(OFD_STATUS_INCORRECT_EEPROM_PARAMETER, &imageInfo); +} + +/**************************************************************************//** +\brief Clears internal flash buffer. +******************************************************************************/ +static void ofdClearFlashInternalBuffer(void) +{ + uint32_t address = 0ul; + uint64_t data; + uint8_t itr; + + if (FLASH_BUSY == ofdCheckBusyState()) + { // waits till flash ready + delayedTransaction = ofdClearFlashInternalBuffer; + ofdStartPollTimer(FLASH_TRANSACTION); + return; + } + + memset((uint8_t *)&data, 0xFF, sizeof(uint64_t)); + + address |= WRITE_BUF1; + GPIO_EXT_MEM_CS_clr(); + HAL_WriteSpi(&spiDesc, (uint8_t *)&address, sizeof(uint32_t)); + for (itr = 0; itr < (PAGE_SIZE / sizeof(uint64_t)); itr++) + HAL_WriteSpi(&spiDesc, (uint8_t *)&data, sizeof(uint64_t)); + GPIO_EXT_MEM_CS_set(); + + ofdWriteData(); +} + +/**************************************************************************//** +\brief Flushs memory buffer to flash. +******************************************************************************/ +void ofdFlushData(void) +{ + if (ALL_DATA_HAS_BEEN_SAVED == flushedPageAddr) + return; + + flushedPageAddr = OFD_LITTLE_TO_BIG_ENDIAN(flushedPageAddr << 1); + flushedPageAddr >>= 8; + flushedPageAddr |= PROGRAM_BUF1; + GPIO_EXT_MEM_CS_clr(); + HAL_WriteSpi(&spiDesc, (uint8_t *)&flushedPageAddr, sizeof(uint32_t)); + GPIO_EXT_MEM_CS_set(); + flushedPageAddr = ALL_DATA_HAS_BEEN_SAVED; +} + +/**************************************************************************//** +\brief Checks image crc. +******************************************************************************/ +void ofdCheckCrc(void) +{ + uint32_t address; + uint32_t pageAddr; + uint32_t byteAddr; + uint8_t atomicCounting = ATOMIC_COUNTING; + + if (FLASH_BUSY == ofdCheckBusyState()) + { // waits till flash ready + delayedTransaction = ofdCheckCrc; + ofdStartPollTimer(FLASH_TRANSACTION); + return; + } + + while (atomicCounting--) + { + pageAddr = localAccessStructure.offset / PAGE_SIZE; + byteAddr = localAccessStructure.offset % PAGE_SIZE; + address = byteAddr | (pageAddr << 9) | ((uint32_t)READ << 24); + address = OFD_LITTLE_TO_BIG_ENDIAN(address); + GPIO_EXT_MEM_CS_clr(); + HAL_WriteSpi(&spiDesc, (uint8_t *)&address, sizeof(uint32_t)); + // load 32 don't care bits + HAL_WriteSpi(&spiDesc, (uint8_t *)&address, sizeof(uint32_t)); + HAL_ReadSpi(&spiDesc, localAccessStructure.data, OFD_BLOCK_FOR_CHECK_CRC); + GPIO_EXT_MEM_CS_set(); // release spi cs + imageInfo.crc = ofdCrc(imageInfo.crc, localAccessStructure.data, OFD_BLOCK_FOR_CHECK_CRC); + localAccessStructure.offset += OFD_BLOCK_FOR_CHECK_CRC; + localAccessStructure.length -= OFD_BLOCK_FOR_CHECK_CRC; + if (!localAccessStructure.length) + { + ofdSaveCrc(); + return; + } + } + // context gap + delayedTransaction = ofdCheckCrc; + ofdStartPollTimer(FLASH_TRANSACTION); +} + +/**************************************************************************//** +\brief Callback for saving internal flash. + +\param[in] status - status of the data flash writing +******************************************************************************/ +void ofdWriteFlashDataCallback(OFD_Status_t status) +{ + uint32_t maxOffset; + + if (OFD_STATUS_SUCCESS != status) + { + if (ofdAuxCallback) + ofdAuxCallback(status); + return; + } + if (OFD_POSITION_1 == sectorNumber) + maxOffset = OFD_IMAGE1_START_ADDRESS + OFD_EEPROM_OFFSET_WITHIN_IMAGE; + else + maxOffset = OFD_IMAGE2_START_ADDRESS + OFD_EEPROM_OFFSET_WITHIN_IMAGE; + + if (localAccessStructure.offset < maxOffset) + { // save mcu flash + ofdSaveCurrentFlashImage(); + return; + } + + internalAccessParam.eepromOffset = 0; + // save eeprom image + ofdSaveCurrentEepromImage(); +} + +/**************************************************************************//** +\brief Starts saving internal flash. +******************************************************************************/ +void ofdSaveCurrentFlashImage(void) +{ + uint16_t itr; + + localAccessStructure.length = OFD_BLOCK_FOR_CHECK_CRC; + localAccessStructure.data = internalAccessParam.data; + for (itr = 0; itr < OFD_BLOCK_FOR_CHECK_CRC; itr++) + { + OFD_LOAD_NO_COMMAND_TO_NVM; + internalAccessParam.data[itr] = ofdReadInternalFlash(internalAccessParam.flashOffset++); + } + internalAccessParam.length -= OFD_BLOCK_FOR_CHECK_CRC; + ofdCallback = ofdWriteFlashDataCallback; + ofdWriteData(); +} + +/**************************************************************************//** +\brief Callback for saving internal eeprom. + +\param[in] status - status of the data eeprom writing +******************************************************************************/ +void ofdWriteEepromDataCallback(OFD_Status_t status) +{ + uint32_t maxOffset; + + if (OFD_STATUS_SUCCESS != status) + { + if (ofdAuxCallback) + ofdAuxCallback(status); + return; + } + if (OFD_POSITION_1 == sectorNumber) + maxOffset = OFD_IMAGE1_START_ADDRESS + OFD_IMAGE_SIZE; + else + maxOffset = OFD_IMAGE2_START_ADDRESS + OFD_IMAGE_SIZE; + + if (localAccessStructure.offset < maxOffset) + { // save mcu eeprom + ofdSaveCurrentEepromImage(); + return; + } + + // start check crc + OFD_FlushAndCheckCrc(sectorNumber, internalAccessParam.data, ofdFlushCrcCallback); +} + +/**************************************************************************//** +\brief Starts saving internal eeprom. +******************************************************************************/ +static void ofdSaveCurrentEepromImage(void) +{ + HAL_EepromParams_t params; + + params.address = internalAccessParam.eepromOffset; + params.data = internalAccessParam.data; + params.length = OFD_BLOCK_FOR_CHECK_CRC; + + if (!ofdEepromHandler(HAL_ReadEeprom(¶ms, ofdSaveCurrentEepromImageContinue), ofdSaveCurrentEepromImage)) + if (ofdAuxCallback) + ofdAuxCallback(OFD_STATUS_INCORRECT_EEPROM_PARAMETER); +} + +/**************************************************************************//** +\brief Continues saving internal flash. +******************************************************************************/ +static void ofdSaveCurrentEepromImageContinue(void) +{ + localAccessStructure.length = OFD_BLOCK_FOR_CHECK_CRC; + localAccessStructure.data = internalAccessParam.data; + if (0 == internalAccessParam.eepromOffset) + memset(internalAccessParam.data, 0xFF, OFD_SERVICE_INFO_SIZE); + + internalAccessParam.eepromOffset += OFD_BLOCK_FOR_CHECK_CRC; + internalAccessParam.length -= OFD_BLOCK_FOR_CHECK_CRC; + ofdCallback = ofdWriteEepromDataCallback; + ofdWriteData(); +} + +/**************************************************************************//** +\brief Callback for start of saving of action for bootloader. + +\param[in] + status - status of the crc saving to eeprom +\param[in] + pInfo - ponter to image information +******************************************************************************/ +static void ofdFlushCrcCallback(OFD_Status_t status, OFD_ImageInfo_t *pInfo) +{ + (void)pInfo; + + if (OFD_STATUS_SUCCESS != status) + { + if (ofdAuxCallback) + ofdAuxCallback(status); + return; + } + ofdSetActionForBootloader(); +} + +/**************************************************************************//** +\brief Sets action for internal bootloader. +******************************************************************************/ +void ofdSetActionForBootloader(void) +{ + HAL_EepromParams_t params; + + params.address = 0; + params.data = (uint8_t *)&actionSector; + params.length = sizeof(OFD_Position_t); + + if (!ofdEepromHandler(HAL_WriteEeprom(¶ms, ofdPollBusyState), ofdSetActionForBootloader)) + if (ofdAuxCallback) + ofdAuxCallback(OFD_STATUS_INCORRECT_EEPROM_PARAMETER); +} + +/**************************************************************************//** +\brief Waits for end of image saving. +******************************************************************************/ +static void ofdPollBusyState(void) +{ + if (FLASH_BUSY == ofdCheckBusyState()) + { // waits till flash ready + delayedTransaction = ofdPollBusyState; + ofdStartPollTimer(FLASH_TRANSACTION); + return; + } + + if (ofdAuxCallback) + ofdAuxCallback(OFD_STATUS_SUCCESS); +} + +/**************************************************************************//** +\brief Reads image crc from internal eeprom. +******************************************************************************/ +void ofdReadCrc(void) +{ + HAL_EepromParams_t params; + + params.address = sectorNumber + 1; + params.data = &imageInfo.crc; + params.length = sizeof(uint8_t); + + if (!ofdEepromHandler(HAL_ReadEeprom(¶ms, ofdSaveCrcCallback), ofdReadCrc)) + if (ofdCallback) + ((OFD_InfoCallback_t)ofdCallback)(OFD_STATUS_INCORRECT_EEPROM_PARAMETER, &imageInfo); +} + +#if defined(_OFD_DEBUG_) +/**************************************************************************//** +\brief Flash read callback. +******************************************************************************/ +void ofdReadConfirm(OFD_Status_t status) +{ + HAL_WriteUsart(&usartDescriptor, debugBuffer, OFD_BLOCK_SIZE); +} + +/**************************************************************************//** +\brief Usart write callback. +******************************************************************************/ +void usartWriteConfirm(void) +{ + debugOffset += OFD_BLOCK_SIZE; + if (debugOffset < OFD_IMAGE_SIZE) + { + ofdReadData(debugOffset, debugBuffer, OFD_BLOCK_SIZE, ofdReadConfirm); + } +} + +/**************************************************************************//** +\brief Initialization of usart for consinsting of flash transmitting. +******************************************************************************/ +void ofdInitDebugInterface(void) +{ +#if defined(ATMEGA1281) || defined(ATMEGA128RFA1) + usartDescriptor.tty = USART_CHANNEL_1; +#elif defined(ATXMEGA256A3) || defined(ATXMEGA256D3) + usartDescriptor.tty = USART_CHANNEL_F0; +#endif + usartDescriptor.mode = USART_MODE_ASYNC; + usartDescriptor.flowControl = USART_FLOW_CONTROL_NONE; + usartDescriptor.baudrate = USART_BAUDRATE_38400; + usartDescriptor.dataLength = USART_DATA8; + usartDescriptor.parity = USART_PARITY_NONE; + usartDescriptor.stopbits = USART_STOPBIT_1; + usartDescriptor.rxBuffer = NULL; + usartDescriptor.rxBufferLength = 0; + usartDescriptor.txBuffer = NULL; + usartDescriptor.txBufferLength = 0; + usartDescriptor.rxCallback = NULL; + usartDescriptor.txCallback = usartWriteConfirm; + + HAL_OpenUsart(&usartDescriptor); + ofdReadData(debugOffset, debugBuffer, OFD_BLOCK_SIZE, ofdReadConfirm); +} + +/**************************************************************************//** +\brief Reads data from the external memory. + +\param[in] + address - flash cell address +\param[out] + data - pointer to memory buffer +\param[in] + size - size of memory buffer +\param[in] + cb - pointer to callback +******************************************************************************/ +void ofdReadData(uint32_t address, uint8_t *data, uint16_t size, OFD_Callback_t cb) +{ + uint32_t pageAddr; + uint32_t byteAddr; + + + while (FLASH_BUSY == ofdCheckBusyState()) + {;}// waits till flash ready + pageAddr = address / PAGE_SIZE; + byteAddr = address % PAGE_SIZE; + address = byteAddr | (pageAddr << 9) | ((uint32_t)READ << 24); + address = OFD_LITTLE_TO_BIG_ENDIAN(address); + GPIO_EXT_MEM_CS_clr(); + HAL_WriteSpi(&spiDesc, (uint8_t *)&address, sizeof(uint32_t)); + // load 32 don't care bits + HAL_WriteSpi(&spiDesc, (uint8_t *)&address, sizeof(uint32_t)); + HAL_ReadSpi(&spiDesc, data, size); + GPIO_EXT_MEM_CS_set(); + if (cb) + cb(OFD_STATUS_SUCCESS); +} +#endif // defined(_OFD_DEBUG_) + +#endif // APP_USE_FAKE_OFD_DRIVER == 0 +#endif // (EXTERNAL_MEMORY == AT45DB041) && (APP_USE_OTAU == 1) +#endif // _OTAU_ +// eof ofdAt25fDriver.c diff --git a/digital/zigbit/bitcloud/stack/Components/HAL/drivers/OFD/src/ofdCommand.c b/digital/zigbit/bitcloud/stack/Components/HAL/drivers/OFD/src/ofdCommand.c new file mode 100644 index 00000000..02a71723 --- /dev/null +++ b/digital/zigbit/bitcloud/stack/Components/HAL/drivers/OFD/src/ofdCommand.c @@ -0,0 +1,243 @@ +/**************************************************************************//** +\file ofdCommand.c + +\brief Implementation of OTAU flash driver interface. + +\author + Atmel Corporation: http://www.atmel.com \n + Support email: avr@atmel.com + + Copyright (c) 2008-2011, Atmel Corporation. All rights reserved. + Licensed under Atmel's Limited License Agreement (BitCloudTM). + +\internal + History: + 7/08/09 A. Khromykh - Created +*******************************************************************************/ +/****************************************************************************** + * WARNING: CHANGING THIS FILE MAY AFFECT CORE FUNCTIONALITY OF THE STACK. * + * EXPERT USERS SHOULD PROCEED WITH CAUTION. * + ******************************************************************************/ + +#ifdef _OTAU_ +#if (APP_USE_OTAU == 1) +#if APP_USE_FAKE_OFD_DRIVER == 0 + +/****************************************************************************** + Includes section +******************************************************************************/ +#include +#include + +/****************************************************************************** + Define(s) section +******************************************************************************/ +#define CRC_INITIALIZATION_VALUE 0xFF + +/****************************************************************************** + Global variables section +******************************************************************************/ +OFD_Position_t sectorNumber = 0; +OFD_Position_t actionSector = 0; +OFD_Callback_t ofdCallback = NULL; +OFD_Callback_t ofdAuxCallback = NULL; +OFD_MemoryAccessParam_t localAccessStructure; +OfdInternalMemoryAccessParam_t internalAccessParam; +OFD_ImageInfo_t imageInfo; +OfdImageTable_t imageTable; + +/****************************************************************************** + Implementations section +******************************************************************************/ +/**************************************************************************//** +\brief Erases image in the external memory. + +\param[in] + pos - image position in the external memory +\param[in] + cb - pointer to callback +******************************************************************************/ +void OFD_EraseImage(OFD_Position_t pos, OFD_Callback_t cb) +{ + if (pos >= OFD_POSITION_MAX) + { + if (cb) + cb(OFD_STATUS_INCORRECT_API_PARAMETER); + return; + } + + sectorNumber = pos; + ofdCallback = cb; + ofdEraseImage(); +} + +/**************************************************************************//** +\brief Writes data to the external memory. + +\param[in] + pos - image position for new data +\param[in] + accessParam - pointer to the access structure +\param[in] + cb - pointer to callback +******************************************************************************/ +void OFD_Write(OFD_Position_t pos, OFD_MemoryAccessParam_t *accessParam, OFD_Callback_t cb) +{ + if ((pos >= OFD_POSITION_MAX) || (NULL == accessParam)) + { + if (cb) + cb(OFD_STATUS_INCORRECT_API_PARAMETER); + return; + } + + sectorNumber = pos; + ofdCallback = cb; + localAccessStructure = *accessParam; + + // set table info like "image was written through api" + imageTable |= (OfdImageTable_t)(1 << pos); + + if (localAccessStructure.offset >= OFD_START_EEPROM_SREC_ADDRESS) + localAccessStructure.offset -= (OFD_START_EEPROM_SREC_ADDRESS - OFD_EEPROM_OFFSET_WITHIN_IMAGE); + + if (OFD_POSITION_1 == sectorNumber) + localAccessStructure.offset += OFD_IMAGE1_START_ADDRESS; + else + localAccessStructure.offset += OFD_IMAGE2_START_ADDRESS; + + ofdWriteData(); +} + +/**************************************************************************//** +\brief Flushes data from internal buffer, checks image crc and saves it to +the external memory. + +\param[in] + pos - image position for new data +\param[in] + countBuff - pointer to the memory for internal data (memory size must be OFD_BLOCK_FOR_CHECK_CRC) +\param[in] + cb - pointer to callback +******************************************************************************/ +void OFD_FlushAndCheckCrc(OFD_Position_t pos, uint8_t *countBuff, OFD_InfoCallback_t cb) +{ + if ((pos >= OFD_POSITION_MAX) || (NULL == countBuff)) + { + if (cb) + cb(OFD_STATUS_INCORRECT_API_PARAMETER, &imageInfo); + return; + } + + ofdFlushData(); + + sectorNumber = pos; + ofdCallback = (OFD_Callback_t)cb; + imageInfo.crc = CRC_INITIALIZATION_VALUE; + + localAccessStructure.data = countBuff; + localAccessStructure.length = OFD_IMAGE_SIZE; + if (OFD_POSITION_1 == sectorNumber) + localAccessStructure.offset = OFD_IMAGE1_START_ADDRESS; + else + localAccessStructure.offset = OFD_IMAGE2_START_ADDRESS; + + ofdCheckCrc(); +} + +/**************************************************************************//** +\brief Saves current mcu flash and eeprom to the external memory, checks crc for its +and set command for bootloader. + +\param[in] + whereToSave - image position for current mcu flash and eeprom +\param[in] + from - new image position +\param[in] + copyBuff - pointer to the memory for internal data (memory size must be OFD_BLOCK_FOR_CHECK_CRC) +\param[in] + cb - pointer to callback +******************************************************************************/ +void OFD_SwitchToNewImage(OFD_Position_t whereToSave, OFD_Position_t from, uint8_t *copyBuff, OFD_Callback_t cb) +{ + if ((whereToSave >= OFD_POSITION_MAX) || (from >= OFD_POSITION_MAX) || (whereToSave == from) || (NULL == copyBuff)) + { + if (cb) + cb(OFD_STATUS_INCORRECT_API_PARAMETER); + return; + } + + sectorNumber = whereToSave; + actionSector = from; + ofdAuxCallback = cb; + + // set table info like "image was saved from mcu" + imageTable &= (OfdImageTable_t)~(1 << sectorNumber); + + internalAccessParam.flashOffset = 0ul; + internalAccessParam.data = copyBuff; + internalAccessParam.length = OFD_IMAGE_SIZE; + + if (OFD_POSITION_1 == sectorNumber) + localAccessStructure.offset = OFD_IMAGE1_START_ADDRESS; + else + localAccessStructure.offset = OFD_IMAGE2_START_ADDRESS; + + ofdSaveCurrentFlashImage(); +} + +/**************************************************************************//** +\brief Reads image informations. + +\param[in] + pos - image position +\param[in] + cb - pointer to callback +******************************************************************************/ +void OFD_ReadImageInfo(OFD_Position_t pos, OFD_InfoCallback_t cb) +{ + if (pos >= OFD_POSITION_MAX) + { + if (cb) + cb(OFD_STATUS_INCORRECT_API_PARAMETER, &imageInfo); + return; + } + + sectorNumber = pos; + + if (imageTable & (1 << pos)) + imageInfo.type = OFD_IMAGE_WAS_WRITTEN_THROUGH_API; + else + imageInfo.type = OFD_IMAGE_WAS_SAVED_FROM_MCU; + + ofdCallback = (OFD_Callback_t)cb; + + ofdReadCrc(); +} + +/**************************************************************************//** +\brief Sets command for bootloader. + +\param[in] + from - image position +\param[in] + cb - pointer to callback +******************************************************************************/ +void OFD_ChangeImage(OFD_Position_t from, OFD_Callback_t cb) +{ + if (from >= OFD_POSITION_MAX) + { + if (cb) + cb(OFD_STATUS_INCORRECT_API_PARAMETER); + return; + } + + actionSector = from; + ofdAuxCallback = cb; + ofdSetActionForBootloader(); +} + +#endif // APP_USE_FAKE_OFD_DRIVER == 0 +#endif // (APP_USE_OTAU == 1) +#endif // _OTAU_ + +// eof ofdCommand.c diff --git a/digital/zigbit/bitcloud/stack/Components/HAL/drivers/OFD/src/ofdCrcService.c b/digital/zigbit/bitcloud/stack/Components/HAL/drivers/OFD/src/ofdCrcService.c new file mode 100644 index 00000000..3ba6ed45 --- /dev/null +++ b/digital/zigbit/bitcloud/stack/Components/HAL/drivers/OFD/src/ofdCrcService.c @@ -0,0 +1,66 @@ +/**************************************************************************//** +\file ofdCrcService.c + +\brief Implementation of crc counting algorithm. + +\author + Atmel Corporation: http://www.atmel.com \n + Support email: avr@atmel.com + + Copyright (c) 2008-2011, Atmel Corporation. All rights reserved. + Licensed under Atmel's Limited License Agreement (BitCloudTM). + +\internal + History: + 7/08/09 A. Khromykh - Created +*******************************************************************************/ +/****************************************************************************** + * WARNING: CHANGING THIS FILE MAY AFFECT CORE FUNCTIONALITY OF THE STACK. * + * EXPERT USERS SHOULD PROCEED WITH CAUTION. * + ******************************************************************************/ + +#ifdef _OTAU_ +#if (APP_USE_OTAU == 1) +#if APP_USE_FAKE_OFD_DRIVER == 0 + +/****************************************************************************** + Includes section +******************************************************************************/ +#include + +/****************************************************************************** + Implementations section +******************************************************************************/ +/**************************************************************************//** +\brief Counts crc current memory area. CRC-8. Polynom 0x31 x^8 + x^5 + x^4 + 1. + +\param[in] + crc - first crc state +\param[in] + pcBlock - pointer to the memory for crc counting +\param[in] + length - memory size + +\return + current area crc +******************************************************************************/ +uint8_t ofdCrc(uint8_t crc, uint8_t *pcBlock, uint8_t length) +{ + uint8_t i; + + while (length--) + { + crc ^= *pcBlock++; + + for (i = 0; i < 8; i++) + crc = crc & 0x80 ? (crc << 1) ^ 0x31 : crc << 1; + } + + return crc; +} + +#endif // APP_USE_FAKE_OFD_DRIVER == 0 +#endif // (APP_USE_OTAU == 1) +#endif // _OTAU_ + +// eof ofdCrcService.c diff --git a/digital/zigbit/bitcloud/stack/Components/HAL/drivers/OFD/src/ofdFakeDriver.c b/digital/zigbit/bitcloud/stack/Components/HAL/drivers/OFD/src/ofdFakeDriver.c new file mode 100644 index 00000000..2d781c70 --- /dev/null +++ b/digital/zigbit/bitcloud/stack/Components/HAL/drivers/OFD/src/ofdFakeDriver.c @@ -0,0 +1,218 @@ +/**************************************************************************//** +\file ofdFakeDriver.c + +\brief Implementation of OTAU fake flash driver. + +\author + Atmel Corporation: http://www.atmel.com \n + Support email: avr@atmel.com + + Copyright (c) 2008-2011, Atmel Corporation. All rights reserved. + Licensed under Atmel's Limited License Agreement (BitCloudTM). + +\internal + History: + 2/06/10 A. Khromykh - Created +*******************************************************************************/ +/****************************************************************************** + * WARNING: CHANGING THIS FILE MAY AFFECT CORE FUNCTIONALITY OF THE STACK. * + * EXPERT USERS SHOULD PROCEED WITH CAUTION. * + ******************************************************************************/ + +#ifdef _OTAU_ +#if (APP_USE_OTAU == 1) +#if APP_USE_FAKE_OFD_DRIVER == 1 + +/****************************************************************************** + Includes section +******************************************************************************/ +#include +#include + +/****************************************************************************** + Define(s) section +******************************************************************************/ +#define CALL_CALLBACK_TIME 10 + +/****************************************************************************** + Prototypes section +******************************************************************************/ +static void ofdRunDriverCb(void); +static void ofdRunInfoDriverCb(void); + +/****************************************************************************** + Global variables section +******************************************************************************/ +static HAL_AppTimer_t ofdCallbackRunner = +{ + .interval = CALL_CALLBACK_TIME, + .mode = TIMER_ONE_SHOT_MODE, +}; +OFD_Callback_t ofdFuncCb = NULL; +OFD_InfoCallback_t ofdFuncInfoCb = NULL; +OFD_ImageInfo_t ofdImageInfo = +{ + .type = OFD_IMAGE_WAS_SAVED_FROM_MCU, + .crc = 0x00 +}; + +/****************************************************************************** + Implementations section +******************************************************************************/ +/**************************************************************************//** +\brief Run flash driver callback if that has been initialized. +******************************************************************************/ +static void ofdRunDriverCb(void) +{ + if (ofdFuncCb) + { + ofdFuncCb(OFD_STATUS_SUCCESS); + } +} + +/**************************************************************************//** +\brief Run flash information driver callback if that has been initialized. +******************************************************************************/ +static void ofdRunInfoDriverCb(void) +{ + if (ofdFuncInfoCb) + { + ofdFuncInfoCb(OFD_STATUS_SUCCESS, &ofdImageInfo); + } +} + +/**************************************************************************//** +\brief Opens serial interface and checks memory type. + +\param[in] + cb - pointer to callback +******************************************************************************/ +void OFD_Open(OFD_Callback_t cb) +{ + ofdFuncCb = cb; + ofdCallbackRunner.callback = ofdRunDriverCb; + HAL_StartAppTimer(&ofdCallbackRunner); +} + +/**************************************************************************//** +\brief Closes serial interface. +******************************************************************************/ +void OFD_Close(void) +{ +} + +/**************************************************************************//** +\brief Erases image in the external memory. + +\param[in] + pos - image position in the external memory +\param[in] + cb - pointer to callback +******************************************************************************/ +void OFD_EraseImage(OFD_Position_t pos, OFD_Callback_t cb) +{ + (void)pos; + ofdFuncCb = cb; + ofdCallbackRunner.callback = ofdRunDriverCb; + HAL_StartAppTimer(&ofdCallbackRunner); +} + +/**************************************************************************//** +\brief Writes data to the external memory. + +\param[in] + pos - image position for new data +\param[in] + accessParam - pointer to the access structure +\param[in] + cb - pointer to callback +******************************************************************************/ +void OFD_Write(OFD_Position_t pos, OFD_MemoryAccessParam_t *accessParam, OFD_Callback_t cb) +{ + (void)pos; + (void)accessParam; + ofdFuncCb = cb; + ofdCallbackRunner.callback = ofdRunDriverCb; + HAL_StartAppTimer(&ofdCallbackRunner); +} + +/**************************************************************************//** +\brief Flushes data from internal buffer, checks image crc and saves it to +the external memory. + +\param[in] + pos - image position for new data +\param[in] + countBuff - pointer to the memory for internal data (memory size must be OFD_BLOCK_FOR_CHECK_CRC) +\param[in] + cb - pointer to callback +******************************************************************************/ +void OFD_FlushAndCheckCrc(OFD_Position_t pos, uint8_t *countBuff, OFD_InfoCallback_t cb) +{ + (void)pos; + (void)countBuff; + ofdFuncInfoCb = cb; + ofdCallbackRunner.callback = ofdRunInfoDriverCb; + HAL_StartAppTimer(&ofdCallbackRunner); +} + +/**************************************************************************//** +\brief Saves current mcu flash and eeprom to the external memory, checks crc for its +and set command for bootloader. + +\param[in] + whereToSave - image position for current mcu flash and eeprom +\param[in] + from - new image position +\param[in] + copyBuff - pointer to the memory for internal data (memory size must be OFD_BLOCK_FOR_CHECK_CRC) +\param[in] + cb - pointer to callback +******************************************************************************/ +void OFD_SwitchToNewImage(OFD_Position_t whereToSave, OFD_Position_t from, uint8_t *copyBuff, OFD_Callback_t cb) +{ + (void)whereToSave; + (void)from; + (void)copyBuff; + ofdFuncCb = cb; + ofdCallbackRunner.callback = ofdRunDriverCb; + HAL_StartAppTimer(&ofdCallbackRunner); +} + +/**************************************************************************//** +\brief Sets command for bootloader. + +\param[in] + from - image position +\param[in] + cb - pointer to callback +******************************************************************************/ +void OFD_ChangeImage(OFD_Position_t from, OFD_Callback_t cb) +{ + (void)from; + ofdFuncCb = cb; + ofdCallbackRunner.callback = ofdRunDriverCb; + HAL_StartAppTimer(&ofdCallbackRunner); +} + +/**************************************************************************//** +\brief Reads image informations. + +\param[in] + pos - image position +\param[in] + cb - pointer to callback +******************************************************************************/ +void OFD_ReadImageInfo(OFD_Position_t pos, OFD_InfoCallback_t cb) +{ + (void)pos; + ofdFuncInfoCb = cb; + ofdCallbackRunner.callback = ofdRunInfoDriverCb; + HAL_StartAppTimer(&ofdCallbackRunner); +} + +#endif // _OTAU_ +#endif // (APP_USE_OTAU == 1) +#endif // APP_USE_FAKE_OFD_DRIVER == 1 + +// eof ofdFakeDriver.c diff --git a/digital/zigbit/bitcloud/stack/Components/HAL/drivers/OFD/src/ofdIntFlashRead.s b/digital/zigbit/bitcloud/stack/Components/HAL/drivers/OFD/src/ofdIntFlashRead.s new file mode 100644 index 00000000..b3267377 --- /dev/null +++ b/digital/zigbit/bitcloud/stack/Components/HAL/drivers/OFD/src/ofdIntFlashRead.s @@ -0,0 +1,40 @@ +/**************************************************************************//** + \file ofdIntFlashRead.s + + \brief Implementation of internal flash reading. + + \author + Atmel Corporation: http://www.atmel.com \n + Support email: avr@atmel.com + + Copyright (c) 2008-2011, Atmel Corporation. All rights reserved. + Licensed under Atmel's Limited License Agreement (BitCloudTM). + + \internal + History: + 13/08/09 A. Khromykh - Created +*******************************************************************************/ + +/******************************************************************************* +Reads byte from internal flash +Parameters: + R25:R24:R23:R22 - Byte address into flash. +Returns: + R24 - read byte from flash. +*******************************************************************************/ +.section .text +.global ofdReadInternalFlash +ofdReadInternalFlash: + push r31 ; Store Z to stack + push r30 ; Store Z to stack + in r25, 0x3B ; Save RAMPZ. + out 0x3B, r24 ; Load RAMPZ with the MSB of the address. + movw r30, r22 ; Move low bytes of address to ZH:ZL from R23:R22 + elpm r24, Z ; Extended load program memory from Z address + out 0x3B, r25 ; Restore RAMPZ register. + pop r30 ; Restore Z + pop r31 ; Restore Z + ret ; return from function + +; eof ofdIntFlashRead.s + diff --git a/digital/zigbit/bitcloud/stack/Components/HAL/drivers/OFD/src/ofdIntFlashRead.s90 b/digital/zigbit/bitcloud/stack/Components/HAL/drivers/OFD/src/ofdIntFlashRead.s90 new file mode 100644 index 00000000..9fc8e941 --- /dev/null +++ b/digital/zigbit/bitcloud/stack/Components/HAL/drivers/OFD/src/ofdIntFlashRead.s90 @@ -0,0 +1,40 @@ +/**************************************************************************//** + \file ofdIntFlashRead.s90 + + \brief Implementation of internal flash reading. + + \author + Atmel Corporation: http://www.atmel.com \n + Support email: avr@atmel.com + + Copyright (c) 2008-2011, Atmel Corporation. All rights reserved. + Licensed under Atmel's Limited License Agreement (BitCloudTM). + + \internal + History: + 19/02/10 A. Khromykh - Created +*******************************************************************************/ + +/******************************************************************************* +Reads byte from internal flash +Parameters: + R19:R18:R17:R16 - Byte address into flash. +Returns: + R16 - read byte from flash. +*******************************************************************************/ +PUBLIC ofdReadInternalFlash +RSEG CODE +ofdReadInternalFlash: + push r31 ; Store Z to stack + push r30 ; Store Z to stack + in r19, 0x3B ; Save RAMPZ. + out 0x3B, r18 ; Load RAMPZ with the MSB of the address. + movw r31:r30, r17:r16 ; Move low bytes of address to ZH:ZL from R17:R16 + elpm r16, Z ; Extended load program memory from Z address + out 0x3B, r19 ; Restore RAMPZ register. + pop r30 ; Restore Z + pop r31 ; Restore Z + ret ; return from function + +; eof ofdIntFlashRead.s90 +END diff --git a/digital/zigbit/bitcloud/stack/Components/HAL/drivers/OFD/src/ofdSpiSerializer.c b/digital/zigbit/bitcloud/stack/Components/HAL/drivers/OFD/src/ofdSpiSerializer.c new file mode 100644 index 00000000..9994f2ed --- /dev/null +++ b/digital/zigbit/bitcloud/stack/Components/HAL/drivers/OFD/src/ofdSpiSerializer.c @@ -0,0 +1,91 @@ +/**************************************************************************//** +\file ofdSerializer.c + +\brief Implementation of capturing of serial interface. + +\author + Atmel Corporation: http://www.atmel.com \n + Support email: avr@atmel.com + + Copyright (c) 2008-2011, Atmel Corporation. All rights reserved. + Licensed under Atmel's Limited License Agreement (BitCloudTM). + +\internal + History: + 7/08/09 A. Khromykh - Created +*******************************************************************************/ +/****************************************************************************** + * WARNING: CHANGING THIS FILE MAY AFFECT CORE FUNCTIONALITY OF THE STACK. * + * EXPERT USERS SHOULD PROCEED WITH CAUTION. * + ******************************************************************************/ + +#ifdef _OTAU_ +#if (APP_USE_OTAU == 1) +#if APP_USE_FAKE_OFD_DRIVER == 0 + +/****************************************************************************** + Includes section +******************************************************************************/ +#include +#include +#include + +/****************************************************************************** + External variables section +******************************************************************************/ +extern OFD_Callback_t ofdCallback; + +/****************************************************************************** + Global variables section +******************************************************************************/ +HAL_SpiDescriptor_t spiDesc; + +/****************************************************************************** + Implementations section +******************************************************************************/ +/**************************************************************************//** +\brief Opens serial interface and checks memory type. + +\param[in] + cb - pointer to callback +******************************************************************************/ +void OFD_Open(OFD_Callback_t cb) +{ + ofdCallback = cb; + +#if defined(ATMEGA1281) || defined(ATMEGA128RFA1) + spiDesc.tty = SPI_CHANNEL_0; + spiDesc.baudRate = SPI_CLOCK_RATE_2000; +#elif defined(ATXMEGA256A3) || defined(ATXMEGA256D3) + spiDesc.tty = SPI_CHANNEL_D; + spiDesc.baudRate = SPI_CLOCK_RATE_8000; +#endif + spiDesc.clockMode = SPI_CLOCK_MODE3; + spiDesc.dataOrder = SPI_DATA_MSB_FIRST; + spiDesc.callback = NULL; + + if (-1 == HAL_OpenSpi(&spiDesc)) + if (ofdCallback) + ofdCallback(OFD_SERIAL_INTERFACE_BUSY); + + GPIO_EXT_MEM_CS_set(); + GPIO_EXT_MEM_CS_make_out(); + ofdFindStorageSpace(); +#if EXTERNAL_MEMORY == AT25DF041A + ofdUnprotectMemorySectors(); +#endif +} + +/**************************************************************************//** +\brief Closes serial interface. +******************************************************************************/ +void OFD_Close(void) +{ + HAL_CloseSpi(&spiDesc); +} + +#endif // APP_USE_FAKE_OFD_DRIVER == 0 +#endif // (APP_USE_OTAU == 1) +#endif // _OTAU_ + +// eof ofdSerialize.c -- cgit v1.2.3