diff --git a/NimaLTD.I-CUBE-SPIF_conf.h b/NimaLTD.I-CUBE-SPIF_conf.h index 822cbe1..966dbff 100644 --- a/NimaLTD.I-CUBE-SPIF_conf.h +++ b/NimaLTD.I-CUBE-SPIF_conf.h @@ -29,12 +29,16 @@ #define SPIF_PLATFORM_HAL 0 #define SPIF_PLATFORM_HAL_DMA 1 +#define SPIF_PLATFORM_OCTOSPI 2 #define SPIF_RTOS_DISABLE 0 #define SPIF_RTOS_CMSIS_V1 1 #define SPIF_RTOS_CMSIS_V2 2 #define SPIF_RTOS_THREADX 3 +#define SPIF_COMPAT_W25XX 0 +#define SPIF_COMPAT_IS25XX 1 + /** MiddleWare name : NimaLTD.I-CUBE-SPIF.2.3.1 MiddleWare fileName : ./NimaLTD.I-CUBE-SPIF_conf.h @@ -43,11 +47,15 @@ #define SPIF_DEBUG SPIF_DEBUG_DISABLE /*---------- SPIF_PLATFORM -----------*/ -#define SPIF_PLATFORM SPIF_PLATFORM_HAL +#define SPIF_PLATFORM SPIF_PLATFORM_OCTOSPI /*---------- SPIF_RTOS -----------*/ #define SPIF_RTOS SPIF_RTOS_DISABLE +/*---------- SPIF_COMPAT -----------*/ +#define SPIF_COMPAT SPIF_COMPAT_IS25XX + + #ifdef __cplusplus } #endif diff --git a/spif.c b/spif.c index b68b3f2..c3a8e5a 100644 --- a/spif.c +++ b/spif.c @@ -4,13 +4,8 @@ ************************************************************************************************************/ #include "spif.h" - -#if SPIF_DEBUG == SPIF_DEBUG_DISABLE -#define dprintf(...) -#else -#include -#define dprintf(...) printf(__VA_ARGS__) -#endif +#include +#include "spif_internal.h" #if SPIF_RTOS == SPIF_RTOS_DISABLE #elif SPIF_RTOS == SPIF_RTOS_CMSIS_V1 @@ -23,1032 +18,65 @@ #include "app_threadx.h" #endif -/************************************************************************************************************ -************** Private Definitions -************************************************************************************************************/ - -#define SPIF_DUMMY_BYTE 0xA5 - -#define SPIF_CMD_READSFDP 0x5A -#define SPIF_CMD_ID 0x90 -#define SPIF_CMD_JEDECID 0x9F -#define SPIF_CMD_UNIQUEID 0x4B -#define SPIF_CMD_WRITEDISABLE 0x04 -#define SPIF_CMD_READSTATUS1 0x05 -#define SPIF_CMD_READSTATUS2 0x35 -#define SPIF_CMD_READSTATUS3 0x15 -#define SPIF_CMD_WRITESTATUSEN 0x50 -#define SPIF_CMD_WRITESTATUS1 0x01 -#define SPIF_CMD_WRITESTATUS2 0x31 -#define SPIF_CMD_WRITESTATUS3 0x11 -#define SPIF_CMD_WRITEENABLE 0x06 -#define SPIF_CMD_ADDR4BYTE_EN 0xB7 -#define SPIF_CMD_ADDR4BYTE_DIS 0xE9 -#define SPIF_CMD_PAGEPROG3ADD 0x02 -#define SPIF_CMD_PAGEPROG4ADD 0x12 -#define SPIF_CMD_READDATA3ADD 0x03 -#define SPIF_CMD_READDATA4ADD 0x13 -#define SPIF_CMD_FASTREAD3ADD 0x0B -#define SPIF_CMD_FASTREAD4ADD 0x0C -#define SPIF_CMD_SECTORERASE3ADD 0x20 -#define SPIF_CMD_SECTORERASE4ADD 0x21 -#define SPIF_CMD_BLOCKERASE3ADD 0xD8 -#define SPIF_CMD_BLOCKERASE4ADD 0xDC -#define SPIF_CMD_CHIPERASE1 0x60 -#define SPIF_CMD_CHIPERASE2 0xC7 -#define SPIF_CMD_SUSPEND 0x75 -#define SPIF_CMD_RESUME 0x7A -#define SPIF_CMD_POWERDOWN 0xB9 -#define SPIF_CMD_RELEASE 0xAB -#define SPIF_CMD_FRAMSERNO 0xC3 - -#define SPIF_STATUS1_BUSY (1 << 0) -#define SPIF_STATUS1_WEL (1 << 1) -#define SPIF_STATUS1_BP0 (1 << 2) -#define SPIF_STATUS1_BP1 (1 << 3) -#define SPIF_STATUS1_BP2 (1 << 4) -#define SPIF_STATUS1_TP (1 << 5) -#define SPIF_STATUS1_SEC (1 << 6) -#define SPIF_STATUS1_SRP0 (1 << 7) - -#define SPIF_STATUS2_SRP1 (1 << 0) -#define SPIF_STATUS2_QE (1 << 1) -#define SPIF_STATUS2_RESERVE1 (1 << 2) -#define SPIF_STATUS2_LB0 (1 << 3) -#define SPIF_STATUS2_LB1 (1 << 4) -#define SPIF_STATUS2_LB2 (1 << 5) -#define SPIF_STATUS2_CMP (1 << 6) -#define SPIF_STATUS2_SUS (1 << 7) - -#define SPIF_STATUS3_RESERVE1 (1 << 0) -#define SPIF_STATUS3_RESERVE2 (1 << 1) -#define SPIF_STATUS3_WPS (1 << 2) -#define SPIF_STATUS3_RESERVE3 (1 << 3) -#define SPIF_STATUS3_RESERVE4 (1 << 4) -#define SPIF_STATUS3_DRV0 (1 << 5) -#define SPIF_STATUS3_DRV1 (1 << 6) -#define SPIF_STATUS3_HOLD (1 << 7) - -/************************************************************************************************************ -************** Private Functions -************************************************************************************************************/ - -void SPIF_Delay(uint32_t Delay); -void SPIF_Lock(SPIF_HandleTypeDef *Handle); -void SPIF_UnLock(SPIF_HandleTypeDef *Handle); -void SPIF_CsPin(SPIF_HandleTypeDef *Handle, bool Select); -bool SPIF_TransmitReceive(SPIF_HandleTypeDef *Handle, uint8_t *Tx, uint8_t *Rx, size_t Size, uint32_t Timeout); -bool SPIF_Transmit(SPIF_HandleTypeDef *Handle, uint8_t *Tx, size_t Size, uint32_t Timeout); -bool SPIF_Receive(SPIF_HandleTypeDef *Handle, uint8_t *Rx, size_t Size, uint32_t Timeout); -bool SPIF_WriteEnable(SPIF_HandleTypeDef *Handle); -bool SPIF_WriteDisable(SPIF_HandleTypeDef *Handle); -uint8_t SPIF_ReadReg1(SPIF_HandleTypeDef *Handle); -uint8_t SPIF_ReadReg2(SPIF_HandleTypeDef *Handle); -uint8_t SPIF_ReadReg3(SPIF_HandleTypeDef *Handle); -bool SPIF_WriteReg1(SPIF_HandleTypeDef *Handle, uint8_t Data); -bool SPIF_WriteReg2(SPIF_HandleTypeDef *Handle, uint8_t Data); -bool SPIF_WriteReg3(SPIF_HandleTypeDef *Handle, uint8_t Data); -bool SPIF_WaitForWriting(SPIF_HandleTypeDef *Handle, uint32_t Timeout); -bool SPIF_FindChip(SPIF_HandleTypeDef *Handle); -bool SPIF_WriteFn(SPIF_HandleTypeDef *Handle, uint32_t PageNumber, uint8_t *Data, uint32_t Size, uint32_t Offset); -bool SPIF_ReadFn(SPIF_HandleTypeDef *Handle, uint32_t Address, uint8_t *Data, uint32_t Size); - -/***********************************************************************************************************/ - -void SPIF_Delay(uint32_t Delay) -{ -#if SPIF_RTOS == SPIF_RTOS_DISABLE - HAL_Delay(Delay); -#elif (SPIF_RTOS == SPIF_RTOS_CMSIS_V1) || (SPIF_RTOS == SPIF_RTOS_CMSIS_V2) - uint32_t d = (configTICK_RATE_HZ * Delay) / 1000; - if (d == 0) - d = 1; - osDelay(d); -#elif SPIF_RTOS == SPIF_RTOS_THREADX - uint32_t d = (TX_TIMER_TICKS_PER_SECOND * Delay) / 1000; - if (d == 0) - d = 1; - tx_thread_sleep(d); -#endif -} - -/***********************************************************************************************************/ - -void SPIF_Lock(SPIF_HandleTypeDef *Handle) -{ - while (Handle->Lock) - { - SPIF_Delay(1); - } - Handle->Lock = 1; -} - -/***********************************************************************************************************/ - -void SPIF_UnLock(SPIF_HandleTypeDef *Handle) -{ - Handle->Lock = 0; -} - -/***********************************************************************************************************/ - -void SPIF_CsPin(SPIF_HandleTypeDef *Handle, bool Select) -{ - HAL_GPIO_WritePin(Handle->Gpio, Handle->Pin, (GPIO_PinState)Select); - for (int i = 0; i < 10; i++); -} - -/***********************************************************************************************************/ - -bool SPIF_TransmitReceive(SPIF_HandleTypeDef *Handle, uint8_t *Tx, uint8_t *Rx, size_t Size, uint32_t Timeout) -{ - bool retVal = false; -#if (SPIF_PLATFORM == SPIF_PLATFORM_HAL) - if (HAL_SPI_TransmitReceive(Handle->HSpi, Tx, Rx, Size, Timeout) == HAL_OK) - { - retVal = true; - } - else - { - dprintf("SPIF TIMEOUT\r\n"); - } -#elif (SPIF_PLATFORM == SPIF_PLATFORM_HAL_DMA) - uint32_t startTime = HAL_GetTick(); - if (HAL_SPI_TransmitReceive_DMA(Handle->HSpi, Tx, Rx, Size) != HAL_OK) - { - dprintf("SPIF TRANSFER ERROR\r\n"); - } - else - { - while (1) - { - SPIF_Delay(1); - if (HAL_GetTick() - startTime >= Timeout) - { - dprintf("SPIF TIMEOUT\r\n"); - HAL_SPI_DMAStop(Handle->HSpi); - break; - } - if (HAL_SPI_GetState(Handle->HSpi) == HAL_SPI_STATE_READY) - { - retVal = true; - break; - } - } - } -#endif - return retVal; -} - -/***********************************************************************************************************/ - -bool SPIF_Transmit(SPIF_HandleTypeDef *Handle, uint8_t *Tx, size_t Size, uint32_t Timeout) -{ - bool retVal = false; -#if (SPIF_PLATFORM == SPIF_PLATFORM_HAL) - if (HAL_SPI_Transmit(Handle->HSpi, Tx, Size, Timeout) == HAL_OK) - { - retVal = true; - } - else - { - dprintf("SPIF TIMEOUT\r\n"); - } -#elif (SPIF_PLATFORM == SPIF_PLATFORM_HAL_DMA) - uint32_t startTime = HAL_GetTick(); - if (HAL_SPI_Transmit_DMA(Handle->HSpi, Tx, Size) != HAL_OK) - { - dprintf("SPIF TRANSFER ERROR\r\n"); - } - else - { - while (1) - { - SPIF_Delay(1); - if (HAL_GetTick() - startTime >= Timeout) - { - dprintf("SPIF TIMEOUT\r\n"); - HAL_SPI_DMAStop(Handle->HSpi); - break; - } - if (HAL_SPI_GetState(Handle->HSpi) == HAL_SPI_STATE_READY) - { - retVal = true; - break; - } - } - } -#endif - return retVal; -} - -/***********************************************************************************************************/ - -bool SPIF_Receive(SPIF_HandleTypeDef *Handle, uint8_t *Rx, size_t Size, uint32_t Timeout) -{ - bool retVal = false; -#if (SPIF_PLATFORM == SPIF_PLATFORM_HAL) - if (HAL_SPI_Receive(Handle->HSpi, Rx, Size, Timeout) == HAL_OK) - { - retVal = true; - } - else - { - dprintf("SPIF TIMEOUT\r\n"); - } -#elif (SPIF_PLATFORM == SPIF_PLATFORM_HAL_DMA) - uint32_t startTime = HAL_GetTick(); - if (HAL_SPI_Receive_DMA(Handle->HSpi, Rx, Size) != HAL_OK) - { - dprintf("SPIF TRANSFER ERROR\r\n"); - } - else - { - while (1) - { - SPIF_Delay(1); - if (HAL_GetTick() - startTime >= Timeout) - { - dprintf("SPIF TIMEOUT\r\n"); - HAL_SPI_DMAStop(Handle->HSpi); - break; - } - if (HAL_SPI_GetState(Handle->HSpi) == HAL_SPI_STATE_READY) - { - retVal = true; - break; - } - } - } -#endif - return retVal; -} - -/***********************************************************************************************************/ - -bool SPIF_WriteEnable(SPIF_HandleTypeDef *Handle) -{ - bool retVal = true; - uint8_t tx[1] = {SPIF_CMD_WRITEENABLE}; - SPIF_CsPin(Handle, 0); - if (SPIF_Transmit(Handle, tx, 1, 100) == false) - { - retVal = false; - dprintf("SPIF_WriteEnable() Error\r\n"); - } - SPIF_CsPin(Handle, 1); - return retVal; -} - -/***********************************************************************************************************/ - -bool SPIF_WriteDisable(SPIF_HandleTypeDef *Handle) -{ - bool retVal = true; - uint8_t tx[1] = {SPIF_CMD_WRITEDISABLE}; - SPIF_CsPin(Handle, 0); - if (SPIF_Transmit(Handle, tx, 1, 100) == false) - { - retVal = false; - dprintf("SPIF_WriteDisable() Error\r\n"); - } - SPIF_CsPin(Handle, 1); - return retVal; -} - -/***********************************************************************************************************/ - -uint8_t SPIF_ReadReg1(SPIF_HandleTypeDef *Handle) -{ - uint8_t retVal = 0; - uint8_t tx[2] = {SPIF_CMD_READSTATUS1, SPIF_DUMMY_BYTE}; - uint8_t rx[2]; - SPIF_CsPin(Handle, 0); - if (SPIF_TransmitReceive(Handle, tx, rx, 2, 100) == true) - { - retVal = rx[1]; - } - SPIF_CsPin(Handle, 1); - return retVal; -} - -/***********************************************************************************************************/ - -uint8_t SPIF_ReadReg2(SPIF_HandleTypeDef *Handle) -{ - uint8_t retVal = 0; - uint8_t tx[2] = {SPIF_CMD_READSTATUS2, SPIF_DUMMY_BYTE}; - uint8_t rx[2]; - SPIF_CsPin(Handle, 0); - if (SPIF_TransmitReceive(Handle, tx, rx, 2, 100) == true) - { - retVal = rx[1]; - } - SPIF_CsPin(Handle, 1); - return retVal; -} - -/***********************************************************************************************************/ - -uint8_t SPIF_ReadReg3(SPIF_HandleTypeDef *Handle) -{ - uint8_t retVal = 0; - uint8_t tx[2] = {SPIF_CMD_READSTATUS3, SPIF_DUMMY_BYTE}; - uint8_t rx[2]; - SPIF_CsPin(Handle, 0); - if (SPIF_TransmitReceive(Handle, tx, rx, 2, 100) == true) - { - retVal = rx[1]; - } - SPIF_CsPin(Handle, 1); - return retVal; -} - -/***********************************************************************************************************/ - -bool SPIF_WriteReg1(SPIF_HandleTypeDef *Handle, uint8_t Data) -{ - bool retVal = true; - uint8_t tx[2] = {SPIF_CMD_WRITESTATUS1, Data}; - uint8_t cmd = SPIF_CMD_WRITESTATUSEN; - do - { - SPIF_CsPin(Handle, 0); - if (SPIF_Transmit(Handle, &cmd, 1, 100) == false) - { - retVal = false; - SPIF_CsPin(Handle, 1); - break; - } - SPIF_CsPin(Handle, 1); - SPIF_CsPin(Handle, 0); - if (SPIF_Transmit(Handle, tx, 2, 100) == false) - { - retVal = false; - SPIF_CsPin(Handle, 1); - break; - } - SPIF_CsPin(Handle, 1); - } while (0); - - return retVal; -} - -/***********************************************************************************************************/ - -bool SPIF_WriteReg2(SPIF_HandleTypeDef *Handle, uint8_t Data) -{ - bool retVal = true; - uint8_t tx[2] = {SPIF_CMD_WRITESTATUS2, Data}; - uint8_t cmd = SPIF_CMD_WRITESTATUSEN; - do - { - SPIF_CsPin(Handle, 0); - if (SPIF_Transmit(Handle, &cmd, 1, 100) == false) - { - retVal = false; - SPIF_CsPin(Handle, 1); - break; - } - SPIF_CsPin(Handle, 1); - SPIF_CsPin(Handle, 0); - if (SPIF_Transmit(Handle, tx, 2, 100) == false) - { - retVal = false; - SPIF_CsPin(Handle, 1); - break; - } - SPIF_CsPin(Handle, 1); - } while (0); - - return retVal; -} - -/***********************************************************************************************************/ - -bool SPIF_WriteReg3(SPIF_HandleTypeDef *Handle, uint8_t Data) -{ - bool retVal = true; - uint8_t tx[2] = {SPIF_CMD_WRITESTATUS3, Data}; - uint8_t cmd = SPIF_CMD_WRITESTATUSEN; - do - { - SPIF_CsPin(Handle, 0); - if (SPIF_Transmit(Handle, &cmd, 1, 100) == false) - { - retVal = false; - SPIF_CsPin(Handle, 1); - break; - } - SPIF_CsPin(Handle, 1); - SPIF_CsPin(Handle, 0); - if (SPIF_Transmit(Handle, tx, 2, 100) == false) - { - retVal = false; - SPIF_CsPin(Handle, 1); - break; - } - SPIF_CsPin(Handle, 1); - } while (0); - - return retVal; -} - -/***********************************************************************************************************/ - -bool SPIF_WaitForWriting(SPIF_HandleTypeDef *Handle, uint32_t Timeout) -{ - bool retVal = false; - uint32_t startTime = HAL_GetTick(); - while (1) - { - SPIF_Delay(1); - if (HAL_GetTick() - startTime >= Timeout) - { - dprintf("SPIF_WaitForWriting() TIMEOUT\r\n"); - break; - } - if ((SPIF_ReadReg1(Handle) & SPIF_STATUS1_BUSY) == 0) - { - retVal = true; - break; - } - } - return retVal; -} - -/***********************************************************************************************************/ - -bool SPIF_FindChip(SPIF_HandleTypeDef *Handle) -{ - uint8_t tx[4] = {SPIF_CMD_JEDECID, 0xFF, 0xFF, 0xFF}; - uint8_t rx[4]; - bool retVal = false; - do - { - dprintf("SPIF_FindChip()\r\n"); - SPIF_CsPin(Handle, 0); - if (SPIF_TransmitReceive(Handle, tx, rx, 4, 100) == false) - { - SPIF_CsPin(Handle, 1); - break; - } - SPIF_CsPin(Handle, 1); - dprintf("CHIP ID: 0x%02X%02X%02X\r\n", rx[1], rx[2], rx[3]); - Handle->Manufactor = rx[1]; - Handle->MemType = rx[2]; - Handle->Size = rx[3]; - - dprintf("SPIF MANUFACTURE: "); - switch (Handle->Manufactor) - { - case SPIF_MANUFACTOR_WINBOND: - dprintf("WINBOND"); - break; - case SPIF_MANUFACTOR_SPANSION: - dprintf("SPANSION"); - break; - case SPIF_MANUFACTOR_MICRON: - dprintf("MICRON"); - break; - case SPIF_MANUFACTOR_MACRONIX: - dprintf("MACRONIX"); - break; - case SPIF_MANUFACTOR_ISSI: - dprintf("ISSI"); - break; - case SPIF_MANUFACTOR_GIGADEVICE: - dprintf("GIGADEVICE"); - break; - case SPIF_MANUFACTOR_AMIC: - dprintf("AMIC"); - break; - case SPIF_MANUFACTOR_SST: - dprintf("SST"); - break; - case SPIF_MANUFACTOR_HYUNDAI: - dprintf("HYUNDAI"); - break; - case SPIF_MANUFACTOR_FUDAN: - dprintf("FUDAN"); - break; - case SPIF_MANUFACTOR_ESMT: - dprintf("ESMT"); - break; - case SPIF_MANUFACTOR_INTEL: - dprintf("INTEL"); - break; - case SPIF_MANUFACTOR_SANYO: - dprintf("SANYO"); - break; - case SPIF_MANUFACTOR_FUJITSU: - dprintf("FUJITSU"); - break; - case SPIF_MANUFACTOR_EON: - dprintf("EON"); - break; - case SPIF_MANUFACTOR_PUYA: - dprintf("PUYA"); - break; - default: - Handle->Manufactor = SPIF_MANUFACTOR_ERROR; - dprintf("ERROR"); - break; - } - dprintf(" - MEMTYPE: 0x%02X", Handle->MemType); - dprintf(" - SIZE: "); - switch (Handle->Size) - { - case SPIF_SIZE_1MBIT: - Handle->BlockCnt = 2; - dprintf("1 MBIT\r\n"); - break; - case SPIF_SIZE_2MBIT: - Handle->BlockCnt = 4; - dprintf("2 MBIT\r\n"); - break; - case SPIF_SIZE_4MBIT: - Handle->BlockCnt = 8; - dprintf("4 MBIT\r\n"); - break; - case SPIF_SIZE_8MBIT: - Handle->BlockCnt = 16; - dprintf("8 MBIT\r\n"); - break; - case SPIF_SIZE_16MBIT: - Handle->BlockCnt = 32; - dprintf("16 MBIT\r\n"); - break; - case SPIF_SIZE_32MBIT: - Handle->BlockCnt = 64; - dprintf("32 MBIT\r\n"); - break; - case SPIF_SIZE_64MBIT: - Handle->BlockCnt = 128; - dprintf("64 MBIT\r\n"); - break; - case SPIF_SIZE_128MBIT: - Handle->BlockCnt = 256; - dprintf("128 MBIT\r\n"); - break; - case SPIF_SIZE_256MBIT: - Handle->BlockCnt = 512; - dprintf("256 MBIT\r\n"); - break; - case SPIF_SIZE_512MBIT: - Handle->BlockCnt = 1024; - dprintf("512 MBIT\r\n"); - break; - default: - Handle->Size = SPIF_SIZE_ERROR; - dprintf("ERROR\r\n"); - break; - } - - Handle->SectorCnt = Handle->BlockCnt * 16; - Handle->PageCnt = (Handle->SectorCnt * SPIF_SECTOR_SIZE) / SPIF_PAGE_SIZE; - dprintf("SPIF BLOCK CNT: %ld\r\n", Handle->BlockCnt); - dprintf("SPIF SECTOR CNT: %ld\r\n", Handle->SectorCnt); - dprintf("SPIF PAGE CNT: %ld\r\n", Handle->PageCnt); - dprintf("SPIF STATUS1: 0x%02X\r\n", SPIF_ReadReg1(Handle)); - dprintf("SPIF STATUS2: 0x%02X\r\n", SPIF_ReadReg2(Handle)); - dprintf("SPIF STATUS3: 0x%02X\r\n", SPIF_ReadReg3(Handle)); - retVal = true; - - } while (0); - - return retVal; -} - -/***********************************************************************************************************/ - -bool SPIF_WriteFn(SPIF_HandleTypeDef *Handle, uint32_t PageNumber, uint8_t *Data, uint32_t Size, uint32_t Offset) -{ - bool retVal = false; - uint32_t address = 0, maximum = SPIF_PAGE_SIZE - Offset; - uint8_t tx[5]; - do - { -#if SPIF_DEBUG != SPIF_DEBUG_DISABLE - uint32_t dbgTime = HAL_GetTick(); -#endif - dprintf("SPIF_WritePage() START PAGE %ld\r\n", PageNumber); - if (PageNumber >= Handle->PageCnt) - { - dprintf("SPIF_WritePage() ERROR PageNumber\r\n"); - break; - } - if (Offset >= SPIF_PAGE_SIZE) - { - dprintf("SPIF_WritePage() ERROR Offset\r\n"); - break; - } - if (Size > maximum) - { - Size = maximum; - } - address = SPIF_PageToAddress(PageNumber) + Offset; -#if SPIF_DEBUG == SPIF_DEBUG_FULL - dprintf("SPIF WRITING {\r\n0x%02X", Data[0]); - for (int i = 1; i < Size; i++) - { - if (i % 8 == 0) - { - dprintf("\r\n"); - } - dprintf(", 0x%02X", Data[i]); - } - dprintf("\r\n}\r\n"); -#endif - if (SPIF_WriteEnable(Handle) == false) - { - break; - } - SPIF_CsPin(Handle, 0); - if (Handle->BlockCnt >= 512) - { - tx[0] = SPIF_CMD_PAGEPROG4ADD; - tx[1] = (address & 0xFF000000) >> 24; - tx[2] = (address & 0x00FF0000) >> 16; - tx[3] = (address & 0x0000FF00) >> 8; - tx[4] = (address & 0x000000FF); - if (SPIF_Transmit(Handle, tx, 5, 100) == false) - { - SPIF_CsPin(Handle, 1); - break; - } - } - else - { - tx[0] = SPIF_CMD_PAGEPROG3ADD; - tx[1] = (address & 0x00FF0000) >> 16; - tx[2] = (address & 0x0000FF00) >> 8; - tx[3] = (address & 0x000000FF); - if (SPIF_Transmit(Handle, tx, 4, 100) == false) - { - SPIF_CsPin(Handle, 1); - break; - } - } - if (SPIF_Transmit(Handle, Data, Size, 1000) == false) - { - SPIF_CsPin(Handle, 1); - break; - } - SPIF_CsPin(Handle, 1); - if (SPIF_WaitForWriting(Handle, 100)) - { - dprintf("SPIF_WritePage() %d BYTES WITERN DONE AFTER %ld ms\r\n", (uint16_t)Size, HAL_GetTick() - dbgTime); - retVal = true; - } - - } while (0); - - SPIF_WriteDisable(Handle); - return retVal; -} - /***********************************************************************************************************/ -bool SPIF_ReadFn(SPIF_HandleTypeDef *Handle, uint32_t Address, uint8_t *Data, uint32_t Size) -{ - bool retVal = false; - uint8_t tx[5]; - do - { -#if SPIF_DEBUG != SPIF_DEBUG_DISABLE - uint32_t dbgTime = HAL_GetTick(); -#endif - dprintf("SPIF_ReadAddress() START ADDRESS %ld\r\n", Address); - SPIF_CsPin(Handle, 0); - if (Handle->BlockCnt >= 512) - { - tx[0] = SPIF_CMD_READDATA4ADD; - tx[1] = (Address & 0xFF000000) >> 24; - tx[2] = (Address & 0x00FF0000) >> 16; - tx[3] = (Address & 0x0000FF00) >> 8; - tx[4] = (Address & 0x000000FF); - if (SPIF_Transmit(Handle, tx, 5, 100) == false) - { - SPIF_CsPin(Handle, 1); - break; - } - } - else - { - tx[0] = SPIF_CMD_READDATA3ADD; - tx[1] = (Address & 0x00FF0000) >> 16; - tx[2] = (Address & 0x0000FF00) >> 8; - tx[3] = (Address & 0x000000FF); - if (SPIF_Transmit(Handle, tx, 4, 100) == false) - { - SPIF_CsPin(Handle, 1); - break; - } - } - uint16_t max_uint16_size = 0xFFFF - 2; - if(Size > max_uint16_size) - { - uint32_t delta = Size; - uint32_t Data_offset = 0; - while(delta > 0) - { - if(delta <= max_uint16_size) - { - if (SPIF_Receive(Handle, (Data+Data_offset), delta, 2000) == false) - { - SPIF_CsPin(Handle, 1); - break; - } - delta = 0; - } - else - { - if (SPIF_Receive(Handle, (Data+Data_offset), max_uint16_size, 2000) == false) - { - SPIF_CsPin(Handle, 1); - break; - } - delta = abs(delta - max_uint16_size); - Data_offset += max_uint16_size; - } - } - if(delta > 0) - { - //break the main do-while loop, so as to return false - break; - } - } - else - { - if(SPIF_Receive(Handle, Data, Size, 2000) == false) - { - SPIF_CsPin(Handle, 1); - break; - } - } - SPIF_CsPin(Handle, 1); - dprintf("SPIF_ReadAddress() %d BYTES READ DONE AFTER %ld ms\r\n", (uint16_t)Size, HAL_GetTick() - dbgTime); -#if SPIF_DEBUG == SPIF_DEBUG_FULL - dprintf("{\r\n0x%02X", Data[0]); - for (int i = 1; i < Size; i++) - { - if (i % 8 == 0) - { - dprintf("\r\n"); - } - dprintf(", 0x%02X", Data[i]); - } - dprintf("\r\n}\r\n"); -#endif - retVal = true; - } while (0); - return retVal; -} + +/***********************************************************************************************************/ /************************************************************************************************************ ************** Public Functions ************************************************************************************************************/ -/** - * @brief Initialize the SPIF. - * @note Enable and configure the SPI and Set GPIO as output for CS pin on the CubeMX - * - * @param *Handle: Pointer to SPIF_HandleTypeDef structure - * @param *HSpi: Pointer to a SPI_HandleTypeDef structure - * @param *Gpio: Pointer to a GPIO_TypeDef structure for CS - * @param Pin: Pin of CS - * - * @retval bool: true or false - */ -bool SPIF_Init(SPIF_HandleTypeDef *Handle, SPI_HandleTypeDef *HSpi, GPIO_TypeDef *Gpio, uint16_t Pin) -{ - bool retVal = false; - do - { - if ((Handle == NULL) || (HSpi == NULL) || (Gpio == NULL) || (Handle->Inited == 1)) - { - dprintf("SPIF_Init() Error, Wrong Parameter\r\n"); - break; - } - memset(Handle, 0, sizeof(SPIF_HandleTypeDef)); - Handle->HSpi = HSpi; - Handle->Gpio = Gpio; - Handle->Pin = Pin; - SPIF_CsPin(Handle, 1); - /* wait for stable VCC */ - while (HAL_GetTick() < 20) - { - SPIF_Delay(1); - } - if (SPIF_WriteDisable(Handle) == false) - { - break; - } - retVal = SPIF_FindChip(Handle); - if (retVal) - { - Handle->Inited = 1; - dprintf("SPIF_Init() Done\r\n"); - } - - } while (0); - - return retVal; -} - -/***********************************************************************************************************/ - -/** - * @brief Full Erase chip. - * @note Send the Full-Erase-chip command and wait for completion - * - * @param *Handle: Pointer to SPIF_HandleTypeDef structure - * - * @retval bool: true or false - */ -bool SPIF_EraseChip(SPIF_HandleTypeDef *Handle) -{ - SPIF_Lock(Handle); - bool retVal = false; - uint8_t tx[1] = {SPIF_CMD_CHIPERASE1}; - do - { -#if SPIF_DEBUG != SPIF_DEBUG_DISABLE - uint32_t dbgTime = HAL_GetTick(); -#endif - dprintf("SPIF_EraseChip() START\r\n"); - if (SPIF_WriteEnable(Handle) == false) - { - break; - } - SPIF_CsPin(Handle, 0); - if (SPIF_Transmit(Handle, tx, 1, 100) == false) - { - SPIF_CsPin(Handle, 1); - break; - } - SPIF_CsPin(Handle, 1); - if (SPIF_WaitForWriting(Handle, Handle->BlockCnt * 1000)) - { - dprintf("SPIF_EraseChip() DONE AFTER %ld ms\r\n", HAL_GetTick() - dbgTime); - retVal = true; - } - - } while (0); - - SPIF_WriteDisable(Handle); - SPIF_UnLock(Handle); - return retVal; -} - -/***********************************************************************************************************/ - -/** - * @brief Erase Sector. - * @note Send the Erase-Sector command and wait for completion - * - * @param *Handle: Pointer to SPIF_HandleTypeDef structure - * @param Sector: Selected Sector - * - * @retval bool: true or false - */ -bool SPIF_EraseSector(SPIF_HandleTypeDef *Handle, uint32_t Sector) -{ - SPIF_Lock(Handle); - bool retVal = false; - uint32_t address = Sector * SPIF_SECTOR_SIZE; - uint8_t tx[5]; - do - { -#if SPIF_DEBUG != SPIF_DEBUG_DISABLE - uint32_t dbgTime = HAL_GetTick(); -#endif - dprintf("SPIF_EraseSector() START SECTOR %ld\r\n", Sector); - if (Sector >= Handle->SectorCnt) - { - dprintf("SPIF_EraseSector() ERROR Sector NUMBER\r\n"); - break; - } - if (SPIF_WriteEnable(Handle) == false) - { - break; - } - SPIF_CsPin(Handle, 0); - if (Handle->BlockCnt >= 512) - { - tx[0] = SPIF_CMD_SECTORERASE4ADD; - tx[1] = (address & 0xFF000000) >> 24; - tx[2] = (address & 0x00FF0000) >> 16; - tx[3] = (address & 0x0000FF00) >> 8; - tx[4] = (address & 0x000000FF); - if (SPIF_Transmit(Handle, tx, 5, 100) == false) - { - SPIF_CsPin(Handle, 1); - break; - } - } - else - { - tx[0] = SPIF_CMD_SECTORERASE3ADD; - tx[1] = (address & 0x00FF0000) >> 16; - tx[2] = (address & 0x0000FF00) >> 8; - tx[3] = (address & 0x000000FF); - if (SPIF_Transmit(Handle, tx, 4, 100) == false) - { - SPIF_CsPin(Handle, 1); - break; - } - } - SPIF_CsPin(Handle, 1); - if (SPIF_WaitForWriting(Handle, 1000)) - { - dprintf("SPIF_EraseSector() DONE AFTER %ld ms\r\n", HAL_GetTick() - dbgTime); - retVal = true; - } - - } while (0); - - SPIF_WriteDisable(Handle); - SPIF_UnLock(Handle); - return retVal; -} - -/***********************************************************************************************************/ /** - * @brief Erase Block. - * @note Send the Erase-Block command and wait for completion - * - * @param *Handle: Pointer to SPIF_HandleTypeDef structure - * @param Sector: Selected Block - * - * @retval bool: true or false - */ -bool SPIF_EraseBlock(SPIF_HandleTypeDef *Handle, uint32_t Block) + * @brief Initialize the SPIF. + * @note Enable and configure the SPI and Set GPIO as output for CS pin on the CubeMX + * + * @param *Handle: Pointer to SPIF_HandleTypeDef structure + * @param *interface: Pointer to either SPI_HandleTypeDef or OSPI_HandleTypeDef structure + * @param *Gpio: Pointer to a GPIO_TypeDef structure for CS + * @param Pin: Pin of CS + * + * @retval bool: true or false + */ +bool SPIF_Init(SPIF_HandleTypeDef *Handle, void *interface, GPIO_TypeDef *Gpio, uint16_t Pin) { - SPIF_Lock(Handle); - bool retVal = false; - uint32_t address = Block * SPIF_BLOCK_SIZE; - uint8_t tx[5]; - do - { -#if SPIF_DEBUG != SPIF_DEBUG_DISABLE - uint32_t dbgTime = HAL_GetTick(); -#endif - dprintf("SPIF_EraseBlock() START PAGE %ld\r\n", Block); - if (Block >= Handle->BlockCnt) - { - dprintf("SPIF_EraseBlock() ERROR Block NUMBER\r\n"); - break; - } - if (SPIF_WriteEnable(Handle) == false) - { - break; - } - SPIF_CsPin(Handle, 0); - if (Handle->BlockCnt >= 512) - { - tx[0] = SPIF_CMD_BLOCKERASE4ADD; - tx[1] = (address & 0xFF000000) >> 24; - tx[2] = (address & 0x00FF0000) >> 16; - tx[3] = (address & 0x0000FF00) >> 8; - tx[4] = (address & 0x000000FF); - if (SPIF_Transmit(Handle, tx, 5, 100) == false) - { - SPIF_CsPin(Handle, 1); - break; - } - } - else + bool retVal = false; + do { - tx[0] = SPIF_CMD_BLOCKERASE3ADD; - tx[1] = (address & 0x00FF0000) >> 16; - tx[2] = (address & 0x0000FF00) >> 8; - tx[3] = (address & 0x000000FF); - if (SPIF_Transmit(Handle, tx, 4, 100) == false) - { + if ((Handle == NULL) || (interface == NULL) || (Gpio == NULL) || (Handle->Inited == 1)) + { + dprintf("SPIF_Init() Error, Wrong Parameter\r\n"); + break; + } + memset(Handle, 0, sizeof(SPIF_HandleTypeDef)); + Handle->interface = interface; + Handle->Gpio = Gpio; + Handle->Pin = Pin; SPIF_CsPin(Handle, 1); - break; - } - } - SPIF_CsPin(Handle, 1); - if (SPIF_WaitForWriting(Handle, 3000)) - { - dprintf("SPIF_EraseBlock() DONE AFTER %ld ms\r\n", HAL_GetTick() - dbgTime); - retVal = true; - } + /* wait for stable VCC */ + while (HAL_GetTick() < 20) + { + SPIF_Delay(1); + } + if (SPIF_WriteDisable(Handle) == false) + { + break; + } + retVal = SPIF_FindChip(Handle); + if (retVal) + { + Handle->Inited = 1; + dprintf("SPIF_Init() Done\r\n"); + } - } while (0); + } while (0); - SPIF_WriteDisable(Handle); - SPIF_UnLock(Handle); - return retVal; + return retVal; } -/***********************************************************************************************************/ /** * @brief Write data array to an Address @@ -1341,3 +369,73 @@ bool SPIF_ReadBlock(SPIF_HandleTypeDef *Handle, uint32_t BlockNumber, uint8_t *D SPIF_UnLock(Handle); return retVal; } + +/* + * @brief Send Command to SPIF + * @note Send command and data to SPIF + * + * @param *Handle: Pointer to SPIF_HandleTypeDef structure + * @param Cmd: Command to send + * @param *Data: Pointer to Data (input), Data can be null + * @param Size: The length of data should be written. (in byte), Size can be 0 + * + * @retval bool: true or false +*/ +bool SPIF_SendCmd(SPIF_HandleTypeDef *Handle, uint8_t Cmd, uint8_t *Data, uint32_t Size){ + bool retVal = false; + uint8_t tx[1] = {Cmd}; + SPIF_CsPin(Handle, 0); + if (SPIF_WriteEnable(Handle) == false) + { + SPIF_CsPin(Handle, 1); + dprintf("SPIF_SendCmd() Error\r\n"); + return retVal; + } + + if (SPIF_Transmit(Handle, tx, 1, 100) == false) + { + SPIF_CsPin(Handle, 1); + dprintf("SPIF_SendCmd() Error\r\n"); + return retVal; + } + + if (Data != NULL && Size > 0) + { + if (SPIF_Transmit(Handle, Data, Size, 100) == false) + { + SPIF_CsPin(Handle, 1); + dprintf("SPIF_SendCmd() Error\r\n"); + return retVal; + } + } + + SPIF_CsPin(Handle, 1); + retVal = true; + return retVal; +} + + +bool SPIF_SendCmdReceive(SPIF_HandleTypeDef *Handle, uint8_t Cmd, uint8_t *RxData, uint32_t Size) +{ + bool retVal = false; + uint8_t tx[1] = {Cmd}; + SPIF_CsPin(Handle, 0); + if (SPIF_WriteEnable(Handle) == false) + { + SPIF_CsPin(Handle, 1); + dprintf("SPIF_SendCmdReceive() Error\r\n"); + return retVal; + } + + if (SPIF_TransmitReceive(Handle, tx, RxData, Size, 100) == false) + { + SPIF_CsPin(Handle, 1); + dprintf("SPIF_SendCmdReceive() Error\r\n"); + return retVal; + } + + SPIF_WriteDisable(Handle); + SPIF_CsPin(Handle, 1); + retVal = true; + return retVal; +} diff --git a/spif.h b/spif.h index 6ad2631..d5db61f 100644 --- a/spif.h +++ b/spif.h @@ -3,158 +3,122 @@ /*********************************************************************************************************** - Author: Nima Askari - Github: https://www.github.com/NimaLTD - LinkedIn: https://www.linkedin.com/in/nimaltd - Youtube: https://www.youtube.com/@nimaltd - Instagram: https://instagram.com/github.NimaLTD + Author: Nima Askari + Github: https://www.github.com/NimaLTD + LinkedIn: https://www.linkedin.com/in/nimaltd + Youtube: https://www.youtube.com/@nimaltd + Instagram: https://instagram.com/github.NimaLTD - Version: 2.3.1 + Version: 2.3.1 - History: - - 2.3.1 - - Fixed SPIF_WriteSector() and SPIF_WriteBlock() - - 2.3.0 - - Added ThreadX Configuration + History: - 2.2.2 - - Compile error + 2.3.1 + - Fixed SPIF_WriteSector() and SPIF_WriteBlock() - 2.2.1 - - Updated SPIF_WriteAddress() + 2.3.0 + - Added ThreadX Configuration - - 2.2.0 - - Added SPI_Trasmit and SPI_Receive again :) + 2.2.2 + - Compile error - 2.1.0 - - Added Support HAL-DMA - - Removed SPI_Trasmit function + 2.2.1 + - Updated SPIF_WriteAddress() - 2.0.1 - - Removed SPI_Receive function - 2.0.0 - - Rewrite again - - Supported STM32CubeMx Packet installer + 2.2.0 + - Added SPI_Trasmit and SPI_Receive again :) -***********************************************************************************************************/ + 2.1.0 + - Added Support HAL-DMA + - Removed SPI_Trasmit function + + 2.0.1 + - Removed SPI_Receive function + + 2.0.0 + - Rewrite again + - Supported STM32CubeMx Packet installer + + ***********************************************************************************************************/ #ifdef __cplusplus extern "C" { #endif -/************************************************************************************************************ -************** Include Headers -************************************************************************************************************/ + /************************************************************************************************************ + ************** Include Headers + ************************************************************************************************************/ #include #include #include "NimaLTD.I-CUBE-SPIF_conf.h" -#include "spi.h" - -/************************************************************************************************************ -************** Public Definitions -************************************************************************************************************/ - -#define SPIF_PAGE_SIZE 0x100 -#define SPIF_SECTOR_SIZE 0x1000 -#define SPIF_BLOCK_SIZE 0x10000 - -#define SPIF_PageToSector(PageNumber) (((PageNumber) * SPIF_PAGE_SIZE) / SPIF_SECTOR_SIZE) -#define SPIF_PageToBlock(PageNumber) (((PageNumber) * SPIF_PAGE_SIZE) / SPIF_BLOCK_SIZE) -#define SPIF_SectorToBlock(SectorNumber) (((SectorNumber) * SPIF_SECTOR_SIZE) / SPIF_BLOCK_SIZE) -#define SPIF_SectorToPage(SectorNumber) (((SectorNumber) * SPIF_SECTOR_SIZE) / SPIF_PAGE_SIZE) -#define SPIF_BlockToPage(BlockNumber) (((BlockNumber) * SPIF_BLOCK_SIZE) / SPIF_PAGE_SIZE) -#define SPIF_PageToAddress(PageNumber) ((PageNumber) * SPIF_PAGE_SIZE) -#define SPIF_SectorToAddress(SectorNumber) ((SectorNumber) * SPIF_SECTOR_SIZE) -#define SPIF_BlockToAddress(BlockNumber) ((BlockNumber) * SPIF_BLOCK_SIZE) -#define SPIF_AddressToPage(Address) ((Address) / SPIF_PAGE_SIZE) -#define SPIF_AddressToSector(Address) ((Address) / SPIF_SECTOR_SIZE) -#define SPIF_AddressToBlock(Address) ((Address) / SPIF_BLOCK_SIZE) - -/************************************************************************************************************ -************** Public struct/enum -************************************************************************************************************/ - -typedef enum -{ - SPIF_MANUFACTOR_ERROR = 0, - SPIF_MANUFACTOR_WINBOND = 0xEF, - SPIF_MANUFACTOR_ISSI = 0xD5, - SPIF_MANUFACTOR_MICRON = 0x20, - SPIF_MANUFACTOR_GIGADEVICE = 0xC8, - SPIF_MANUFACTOR_MACRONIX = 0xC2, - SPIF_MANUFACTOR_SPANSION = 0x01, - SPIF_MANUFACTOR_AMIC = 0x37, - SPIF_MANUFACTOR_SST = 0xBF, - SPIF_MANUFACTOR_HYUNDAI = 0xAD, - SPIF_MANUFACTOR_ATMEL = 0x1F, - SPIF_MANUFACTOR_FUDAN = 0xA1, - SPIF_MANUFACTOR_ESMT = 0x8C, - SPIF_MANUFACTOR_INTEL = 0x89, - SPIF_MANUFACTOR_SANYO = 0x62, - SPIF_MANUFACTOR_FUJITSU = 0x04, - SPIF_MANUFACTOR_EON = 0x1C, - SPIF_MANUFACTOR_PUYA = 0x85, - -} SPIF_ManufactorTypeDef; - -typedef enum -{ - SPIF_SIZE_ERROR = 0, - SPIF_SIZE_1MBIT = 0x11, - SPIF_SIZE_2MBIT = 0x12, - SPIF_SIZE_4MBIT = 0x13, - SPIF_SIZE_8MBIT = 0x14, - SPIF_SIZE_16MBIT = 0x15, - SPIF_SIZE_32MBIT = 0x16, - SPIF_SIZE_64MBIT = 0x17, - SPIF_SIZE_128MBIT = 0x18, - SPIF_SIZE_256MBIT = 0x19, - SPIF_SIZE_512MBIT = 0x20, - -} SPIF_SizeTypeDef; - -typedef struct -{ - SPI_HandleTypeDef *HSpi; - GPIO_TypeDef *Gpio; - SPIF_ManufactorTypeDef Manufactor; - SPIF_SizeTypeDef Size; - uint8_t Inited; - uint8_t MemType; - uint8_t Lock; - uint8_t Reserved; - uint32_t Pin; - uint32_t PageCnt; - uint32_t SectorCnt; - uint32_t BlockCnt; - -} SPIF_HandleTypeDef; - -/************************************************************************************************************ -************** Public Functions -************************************************************************************************************/ - -bool SPIF_Init(SPIF_HandleTypeDef *Handle, SPI_HandleTypeDef *HSpi, GPIO_TypeDef *Gpio, uint16_t Pin); - -bool SPIF_EraseChip(SPIF_HandleTypeDef *Handle); -bool SPIF_EraseSector(SPIF_HandleTypeDef *Handle, uint32_t Sector); -bool SPIF_EraseBlock(SPIF_HandleTypeDef *Handle, uint32_t Block); - -bool SPIF_WriteAddress(SPIF_HandleTypeDef *Handle, uint32_t Address, uint8_t *Data, uint32_t Size); -bool SPIF_WritePage(SPIF_HandleTypeDef *Handle, uint32_t PageNumber, uint8_t *Data, uint32_t Size, uint32_t Offset); -bool SPIF_WriteSector(SPIF_HandleTypeDef *Handle, uint32_t SectorNumber, uint8_t *Data, uint32_t Size, uint32_t Offset); -bool SPIF_WriteBlock(SPIF_HandleTypeDef *Handle, uint32_t BlockNumber, uint8_t *Data, uint32_t Size, uint32_t Offset); - -bool SPIF_ReadAddress(SPIF_HandleTypeDef *Handle, uint32_t Address, uint8_t *Data, uint32_t Size); -bool SPIF_ReadPage(SPIF_HandleTypeDef *Handle, uint32_t PageNumber, uint8_t *Data, uint32_t Size, uint32_t Offset); -bool SPIF_ReadSector(SPIF_HandleTypeDef *Handle, uint32_t SectorNumber, uint8_t *Data, uint32_t Size, uint32_t Offset); -bool SPIF_ReadBlock(SPIF_HandleTypeDef *Handle, uint32_t BlockNumber, uint8_t *Data, uint32_t Size, uint32_t Offset); +#include "spif_common.h" + +#if (SPIF_INTERFACE == SPIF_INTERFACE_OCTOSPI) +#include "stm32u5xx_hal.h" +#include "stm32u5xx_hal_ospi.h" +#else +#include "stm32u5xx_hal_spi.h" +#endif + + + +#if (SPIF_COMPAT == SPIF_COMPAT_W25XX) +#include "spif_compat_w25xx.h" + +#elif (SPIF_COMPAT == SPIF_COMPAT_IS25XX) +#include "spif_compat_is25xx.h" + +#endif + +// #if (SPIF_PLATFORM == SPIF_INTERFACE_OCTOSPI) +// #include "spif_interface_octospi.h" +//#else +// +//#include "spif_interface_spi.h" +// +//#endif + + + + /************************************************************************************************************ + ************** Public Functions + ************************************************************************************************************/ +//#if (SPIF_PLATFORM == SPIF_PLATFORM_OCTOSPI) +// bool SPIF_OCTOSPI_Init(SPIF_HandleTypeDef *Handle, +// OSPI_HandleTypeDef *HOspi, GPIO_TypeDef *Gpio, uint16_t Pin); +//#else +// bool SPIF_Init(SPIF_HandleTypeDef *Handle, SPI_HandleTypeDef *HSpi, GPIO_TypeDef *Gpio, uint16_t Pin); +//#endif + + bool SPIF_WriteAddress(SPIF_HandleTypeDef *Handle, uint32_t Address, + uint8_t *Data, uint32_t Size); + bool SPIF_WritePage(SPIF_HandleTypeDef *Handle, uint32_t PageNumber, + uint8_t *Data, uint32_t Size, uint32_t Offset); + bool SPIF_WriteSector(SPIF_HandleTypeDef *Handle, uint32_t SectorNumber, + uint8_t *Data, uint32_t Size, uint32_t Offset); + bool SPIF_WriteBlock(SPIF_HandleTypeDef *Handle, uint32_t BlockNumber, + uint8_t *Data, uint32_t Size, uint32_t Offset); + + bool SPIF_ReadAddress(SPIF_HandleTypeDef *Handle, uint32_t Address, + uint8_t *Data, uint32_t Size); + bool SPIF_ReadPage(SPIF_HandleTypeDef *Handle, uint32_t PageNumber, + uint8_t *Data, uint32_t Size, uint32_t Offset); + bool SPIF_ReadSector(SPIF_HandleTypeDef *Handle, uint32_t SectorNumber, + uint8_t *Data, uint32_t Size, uint32_t Offset); + bool SPIF_ReadBlock(SPIF_HandleTypeDef *Handle, uint32_t BlockNumber, + uint8_t *Data, uint32_t Size, uint32_t Offset); + + bool SPIF_SendCmd(SPIF_HandleTypeDef *Handle, uint8_t Cmd, uint8_t *Data, + uint32_t Size); + bool SPIF_SendCmdReceive(SPIF_HandleTypeDef *Handle, uint8_t Cmd, + uint8_t *RxData, uint32_t Size); + +#if (SPIF_COMPAT == SPIF_COMPAT_IS25XX) + bool SPIF_QPI_Enable(SPIF_HandleTypeDef *Handle); +#endif #ifdef __cplusplus } diff --git a/spif_common.h b/spif_common.h new file mode 100644 index 0000000..1781d2d --- /dev/null +++ b/spif_common.h @@ -0,0 +1,104 @@ +/* + * spif_common.h + * + * Created on: Jun 2, 2025 + * Author: Megh Shah + */ + +#ifndef INC_SPIF_COMMON_H_ +#define INC_SPIF_COMMON_H_ + +#include +#include "stm32u5xx_hal.h" +#include + + + + +#if SPIF_DEBUG == SPIF_DEBUG_DISABLE +#define dprintf(...) +#else +#include +#define dprintf(...) printf(__VA_ARGS__) +#endif + + + +/************************************************************************************************************ + ************** Public struct/enum + ************************************************************************************************************/ + +typedef enum { + SPIF_MANUFACTOR_ERROR = 0, + SPIF_MANUFACTOR_WINBOND = 0xEF, + SPIF_MANUFACTOR_ISSI = 0xD5, + SPIF_MANUFACTOR_MICRON = 0x20, + SPIF_MANUFACTOR_GIGADEVICE = 0xC8, + SPIF_MANUFACTOR_MACRONIX = 0xC2, + SPIF_MANUFACTOR_SPANSION = 0x01, + SPIF_MANUFACTOR_AMIC = 0x37, + SPIF_MANUFACTOR_SST = 0xBF, + SPIF_MANUFACTOR_HYUNDAI = 0xAD, + SPIF_MANUFACTOR_ATMEL = 0x1F, + SPIF_MANUFACTOR_FUDAN = 0xA1, + SPIF_MANUFACTOR_ESMT = 0x8C, + SPIF_MANUFACTOR_INTEL = 0x89, + SPIF_MANUFACTOR_SANYO = 0x62, + SPIF_MANUFACTOR_FUJITSU = 0x04, + SPIF_MANUFACTOR_EON = 0x1C, + SPIF_MANUFACTOR_PUYA = 0x85, + +} SPIF_ManufactorTypeDef; + +typedef enum { + SPIF_SIZE_ERROR = 0, + SPIF_SIZE_1MBIT = 0x11, + SPIF_SIZE_2MBIT = 0x12, + SPIF_SIZE_4MBIT = 0x13, + SPIF_SIZE_8MBIT = 0x14, + SPIF_SIZE_16MBIT = 0x15, + SPIF_SIZE_32MBIT = 0x16, + SPIF_SIZE_64MBIT = 0x17, + SPIF_SIZE_128MBIT = 0x18, + SPIF_SIZE_256MBIT = 0x19, + SPIF_SIZE_512MBIT = 0x20, + +} SPIF_SizeTypeDef; + +typedef struct { + // --- Instruction Phase --- + bool instructionEnabled; + uint8_t instructionSize; + uint8_t instruction; + + // --- Address Phase --- + bool addressEnabled; + uint8_t addressSize; + uint32_t address; + + // Dummy Cycles --- + uint8_t dummyCycles; + + // --- Data Phase --- + bool dataEnabled; +} SPIF_EmulatedPhases; + +typedef struct { + void *interface; + GPIO_TypeDef *Gpio; + SPIF_ManufactorTypeDef Manufactor; + SPIF_SizeTypeDef Size; + uint8_t Inited; + uint8_t MemType; + uint8_t Lock; + uint8_t Reserved; + uint32_t Pin; + uint32_t PageCnt; + uint32_t SectorCnt; + uint32_t BlockCnt; + + SPIF_EmulatedPhases phase_config; +} SPIF_HandleTypeDef; + + +#endif /* INC_SPIF_COMMON_H_ */ diff --git a/spif_compat_is25xx.c b/spif_compat_is25xx.c new file mode 100644 index 0000000..612e164 --- /dev/null +++ b/spif_compat_is25xx.c @@ -0,0 +1,710 @@ +#include "spif_compat_is25xx.h" +#include "spif.h" + +#if (SPIF_COMPAT == SPIF_COMPAT_IS25XX) +/*Register Definitions for IS25XX*/ + +#define SPIF_DUMMY_BYTE 0xA5 //TODO: confirm value + +#define SPIF_CMD_READDATA3ADD 0x03 +#define SPIF_CMD_READDATA4ADD 0x13 +#define SPIF_CMD_FASTREAD3ADD 0x0B +#define SPIF_CMD_FASTREAD4ADD 0x0C +#define SPIF_CMD_FASTREADDUALIO3ADD 0xBB +#define SPIF_CMD_FASTREADDUALIO4ADD 0xBC +#define SPIF_CMD_FASTREADDUALOUTPUT3ADD 0x3B +#define SPIF_CMD_FASTREADDUALOUTPUT4ADD 0x3C +#define SPIF_CMD_FASTREADQUADIO3ADD 0xEB +#define SPIF_CMD_FASTREADQUADIO4ADD 0xEC +#define SPIF_CMD_FASTREADQUADOUTPUT3ADD 0x6B +#define SPIF_CMD_FASTREADQUADOUTPUT4ADD 0x6C +#define SPIF_CMD_FASTREADDTRIO3ADD 0x0D +#define SPIF_CMD_FASTREADDTRIO4ADD 0x0E +#define SPIF_CMD_FASTREADDTRDUALIO3ADD 0xBD +#define SPIF_CMD_FASTREADDTRDUALIO4ADD 0xBE +#define SPIF_CMD_FASTREADQUADDTRIO3ADD 0xED +#define SPIF_CMD_FASTREADQUADDTRIO4ADD 0xEE +#define SPIF_CMD_PAGEPROG3ADD 0x02 +#define SPIF_CMD_PAGEPROG4ADD 0x12 +#define SPIF_CMD_QUADPAGEPROGRAM3ADD 0x32 +#define SPIF_CMD_QUADPAGEPROGRAM4ADD 0x34 +#define SPIF_CMD_SECTORERASE3ADD 0x20 +#define SPIF_CMD_SECTORERASE4ADD 0x21 +#define SPIF_CMD_BLOCKERASE32K3ADD 0x52 +#define SPIF_CMD_BLOCKERASE32K4ADD 0x5C +#define SPIF_CMD_BLOCKERASE64K3ADD 0xD8 +#define SPIF_CMD_BLOCKERASE64K4ADD 0xDC +#define SPIF_CMD_CHIPERASE1 0xC7 +#define SPIF_CMD_WRITEENABLE 0x06 +#define SPIF_CMD_WRITEDISABLE 0x04 +#define SPIF_CMD_READSTATUS1 0x05 +#define SPIF_CMD_WRITESTATUS1 0x01 +#define SPIF_CMD_READFNREG 0x48 +#define SPIF_CMD_WRITEFNREG 0x42 +#define SPIF_CMD_ENTERQPI 0x35 +#define SPIF_CMD_EXITQPI 0xF5 +#define SPIF_CMD_SUSPEND 0x75 +#define SPIF_CMD_RESUME 0x7A +#define SPIF_CMD_DEEPPOWERDOWN 0xB9 +#define SPIF_CMD_READID 0xAB +#define SPIF_CMD_RELEASEPOWERDOWN 0xAB +#define SPIF_CMD_SETREADPARAMNONVOLATILE 0x65 +#define SPIF_CMD_SETREADPARAMVOLATILE 0xC0 +#define SPIF_CMD_SETEXTENDEDREADPARAMNONVOLATILE 0x85 +#define SPIF_CMD_SETEXTEDEDREADPARAMVOLATILE 0x83 +#define SPIF_CMD_READREADPARAMVOLATILE 0x61 +#define SPIF_CMD_READREADEXTENDEDPARAMVOLATILE 0x81 +#define SPIF_CMD_CLEAREXTENDEDREADREG 0x82 +#define SPIF_CMD_JEDECID 0x9F +#define SPIF_CMD_READMANUFACTURERID 0x90 +#define SPIF_CMD_READJEDECIDQPI 0xAF +#define SPIF_CMD_READUNIQUEID 0x4B +#define SPIF_CMD_READSFDP 0x5A +#define SPIF_CMD_NOOP 0x00 +#define SPIF_CMD_SOFTRESETENABLE 0x66 +#define SPIF_CMD_SOFTRESET 0x99 +#define SPIF_CMD_ERASEINFOROW 0x64 +#define SPIF_CMD_PROGRAMINFOROW 0x62 +#define SPIF_CMD_READINFOROW 0x68 +#define SPIF_CMD_SECTORUNLOCK3ADD 0x26 +#define SPIF_CMD_SECTORUNLOCK4ADD 0x25 +#define SPIF_CMD_SECTORLOCK 0x24 +#define SPIF_CMD_READAUTOBOOTREG 0x14 +#define SPIF_CMD_WRITEAUTOBOOTREG 0x15 +#define SPIF_CMD_READBANKADDRESSREG 0x16 +#define SPIF_CMD_WRITEBANKADDRESSREGVOLATILE 0x17 +#define SPIF_CMD_WRITEBANKADDRESSREGNONVOLATILE 0x18 +#define SPIF_CMD_ENTER4ADD 0xB7 +#define SPIF_CMD_EXIT4ADD 0x29 +#define SPIF_CMD_READDYB3ADD 0xFA +#define SPIF_CMD_READDYB4ADD 0xE0 +#define SPIF_CMD_WRITEDYB3ADD 0xFB +#define SPIF_CMD_WRITEDYB4ADD 0xE1 +#define SPIF_CMD_READPPB3ADD 0xFC +#define SPIF_CMD_READPPB4ADD 0xE2 +#define SPIF_CMD_PROGPPB3ADD 0xFD +#define SPIF_CMD_PROGPPB4ADD 0xE3 +#define SPIF_CMD_ERASEPPB 0xE4 +#define SPIF_CMD_READASP 0x2B +#define SPIF_CMD_PROGRMASP 0x2F +#define SPIF_CMD_READPPBLOCKBIT 0xA7 +#define SPIF_CMD_WRITEPPBLOCKBIT 0xA6 +#define SPIF_CMD_SETFREEZEBIT 0x91 +#define SPIF_CMD_READPASSWORD 0xE7 +#define SPIF_CMD_PROGRAMPASSWORD 0xE8 +#define SPIF_CMD_UNLOCKPASSWORD 0xE9 +#define SPIF_CMD_SETALLDYBBITS 0x7E +#define SPIF_CMD_CLEARALLDYBBITS 0x98 + +/*status register definitions*/ +#define SPIF_STATUS_WIP (1 << 0) +#define SPIF_STATUS_WEL (1 << 1) +#define SPIF_STATUS_BP0 (1 << 2) +#define SPIF_STATUS_BP1 (1 << 3) +#define SPIF_STATUS_BP2 (1 << 4) +#define SPIF_STATUS_BP3 (1 << 5) +#define SPIF_STATUS_QE (1 << 6) +#define SPIF_STATUS_SRWD (1 << 7) + +/*Function Register definitions*/ +#define SPIF_FNREG_DEDICATEDRESET (1 << 0) +#define SPIF_FNREG_TBS (1 << 1) +#define SPIF_FNREG_PSUS (1 << 2) +#define SPIF_FNREG_ESUS (1 << 3) +#define SPIF_FNREG_IRLOCK0 (1 << 4) +#define SPIF_FNREG_IRLOCK1 (1 << 5) +#define SPIF_FNREG_IRLOCK2 (1 << 6) +#define SPIF_FNREG_IRLOCK3 (1 << 7) + +/*Read Register definitons*/ +#define SPIF_READREG_BURSTLEN0 (1 << 0) +#define SPIF_READREG_BURSTLEN1 (1 << 1) +#define SPIF_READREG_BURSTLENENABLE (1 << 2) +#define SPIF_READREG_DUMMYCYCLES0 (1 << 3) +#define SPIF_READREG_DUMMYCYCLES1 (1 << 4) +#define SPIF_READREG_DUMMYCYCLES2 (1 << 5) +#define SPIF_READREG_DUMMYCYCLES3 (1 << 6) +#define SPIF_READREG_HOLD_RESET (1 << 7) + +/*Extended Read Register definitions*/ +#define SPIF_EXTENDEDREADREG_WIP (1 << 0) +#define SPIF_EXTENDEDREADREG_PROT_E (1 << 1) +#define SPIF_EXTENDEDREADREG_P_ERR (1 << 2) +#define SPIF_EXTENDEDREADREG_E_ERR (1 << 3) +// bit 4 is reserved +#define SPIF_EXTENDEDREADREG_ODS0 (1 << 5) +#define SPIF_EXTENDEDREADREG_ODS1 (1 << 6) +#define SPIF_EXTENDEDREADREG_ODS2 (1 << 7) + +/* AutoBoot Register definitions */ +#define SPIF_AUTOBootREG_ABSA (0xFFFFFFE0) // Bits AB[31:5] - AutoBoot Start Address +#define SPIF_AUTOBootREG_ABSD (0x0000001E) // Bits AB[4:1] - AutoBoot Start Delay +#define SPIF_AUTOBootREG_ABE (1 << 0) // Bit AB[0] - AutoBoot Enable + +/* Bank Address Register*/ +#define SPIF_BANKADDRESSREG_EXTADD (1 << 7) //3-byte or 4-byte addressing selection Bit +//other bits are all reserved + +/* Advanced Sector/Block Protection Register (ASPR) definitions */ +// bit 0 is reserved +#define SPIF_ASPR_PSTMLB (1 << 1) // Persistent Protection Mode Lock Bit +#define SPIF_ASPR_PWDMLB (1 << 2) // Password Protection Mode Lock Bit +//bit 3 to 14 are reserved +#define SPIF_ASPR_TBPARM (1 << 15) // Top/Bottom Parameter Sector + +/*Password Register*/ +// TODO: define the password register bits +/*PPB Lock Register*/ +#define SPIF_PPBLOCKREG_PPBLOCK (1 << 0) //PPB Lock Bit +//bit 1 to 6 are reserved +#define SPIF_PPBLOCKREG_FREEZE (1 << 7) + +/*PPB Register*/ +//TODO: confirm if need this definition +/*DYB register*/ +//TODO: confirm if need this definition + +bool SPIF_WriteEnable(SPIF_HandleTypeDef *Handle) { + bool retVal = true; + uint8_t tx[1] = { SPIF_CMD_WRITEENABLE }; + + SPIF_SetInstructionPhase(Handle, true, 1, SPIF_CMD_WRITEENABLE); + SPIF_SetAddressPhase(Handle, false, 0, 0); + SPIF_SetDummyCycles(Handle, 0); + SPIF_SetDataPhase(Handle, false); + + SPIF_CsPin(Handle, 0); + if (SPIF_Transmit(Handle, tx, 1, 100) == false) { + retVal = false; + dprintf("SPIF_WriteEnable() Error\r\n"); + } + SPIF_CsPin(Handle, 1); + return retVal; +} + +bool SPIF_WriteDisable(SPIF_HandleTypeDef *Handle) { + bool retVal = true; + uint8_t tx[1] = { SPIF_CMD_WRITEDISABLE }; + + SPIF_SetInstructionPhase(Handle, true, 1, SPIF_CMD_WRITEDISABLE); + SPIF_SetAddressPhase(Handle, false, 0, 0); + SPIF_SetDummyCycles(Handle, 0); + SPIF_SetDataPhase(Handle, false); + + SPIF_CsPin(Handle, 0); + if (SPIF_Transmit(Handle, tx, 1, 100) == false) { + retVal = false; + dprintf("SPIF_WriteDisable() Error\r\n"); + } + SPIF_CsPin(Handle, 1); + return retVal; +} + +bool SPIF_WaitForWriting(SPIF_HandleTypeDef *Handle, uint32_t Timeout) { + bool retVal = false; + uint32_t startTime = HAL_GetTick(); + while (1) { + SPIF_Delay(1); + if (HAL_GetTick() - startTime >= Timeout) { + dprintf("SPIF_WaitForWriting() TIMEOUT\r\n"); + break; + } + if ((SPIF_ReadReg1(Handle) & SPIF_STATUS_WIP) == 0) + + { + retVal = true; + break; + } + } + return retVal; +} + +uint8_t SPIF_ReadReg1(SPIF_HandleTypeDef *Handle) { + uint8_t retVal = 0; +// uint8_t tx[2] = { SPIF_CMD_READSTATUS1, SPIF_DUMMY_BYTE }; + uint8_t rx[2]; + + SPIF_SetInstructionPhase(Handle, true, 1, SPIF_CMD_READSTATUS1); + SPIF_SetAddressPhase(Handle, false, 0, 0); + SPIF_SetDummyCycles(Handle, 1); + SPIF_SetDataPhase(Handle, false); + + SPIF_CsPin(Handle, 0); + if (SPIF_Receive(Handle, rx, 2, 100) == true) { + retVal = rx[1]; + } + SPIF_CsPin(Handle, 1); + return retVal; +} + +bool SPIF_WriteReg1(SPIF_HandleTypeDef *Handle, uint8_t Data) { + bool retVal = true; + uint8_t tx[1] = { Data }; + + SPIF_SetInstructionPhase(Handle, true, 1, SPIF_CMD_WRITESTATUS1); + SPIF_SetAddressPhase(Handle, false, 0, 0); + SPIF_SetDummyCycles(Handle, 0); + SPIF_SetDataPhase(Handle, true); + + do { + + if (SPIF_WriteEnable(Handle) == false) { + retVal = false; + break; + } + + SPIF_CsPin(Handle, 0); + if (SPIF_Transmit(Handle, tx, 1, 100) == false) { + retVal = false; + SPIF_CsPin(Handle, 1); + break; + } + SPIF_CsPin(Handle, 1); + } while (0); + + return retVal; +} + +bool SPIF_WriteFn(SPIF_HandleTypeDef *Handle, uint32_t PageNumber, + uint8_t *Data, uint32_t Size, uint32_t Offset) { + bool retVal = false; + uint32_t address = 0, maximum = SPIF_PAGE_SIZE - Offset; +// uint8_t tx[5] = { 0 }; + do { +#if SPIF_DEBUG != SPIF_DEBUG_DISABLE + uint32_t dbgTime = HAL_GetTick(); +#endif + dprintf("SPIF_WritePage() START PAGE %ld\r\n", PageNumber); + if (PageNumber >= Handle->PageCnt) { + dprintf("SPIF_WritePage() ERROR PageNumber\r\n"); + break; + } + if (Offset >= SPIF_PAGE_SIZE) { + dprintf("SPIF_WritePage() ERROR Offset\r\n"); + break; + } + if (Size > maximum) { + Size = maximum; + } + address = SPIF_PageToAddress(PageNumber) + Offset; +#if SPIF_DEBUG == SPIF_DEBUG_FULL + dprintf("SPIF WRITING {\r\n0x%02X", Data[0]); + for (int i = 1; i < Size; i++) + { + if (i % 8 == 0) + { + dprintf("\r\n"); + } + dprintf(", 0x%02X", Data[i]); + } + dprintf("\r\n}\r\n"); +#endif + if (SPIF_WriteEnable(Handle) == false) { + break; + } + SPIF_CsPin(Handle, 0); + if (Handle->BlockCnt >= 512) { + SPIF_SetInstructionPhase(Handle, true, 1, SPIF_CMD_PAGEPROG4ADD); + SPIF_SetAddressPhase(Handle, true, 4, address); + SPIF_SetDummyCycles(Handle, 0); + SPIF_SetDataPhase(Handle, true); + + if (SPIF_Transmit(Handle, Data, Size, 1000) == false) { + SPIF_CsPin(Handle, 1); + break; + } + + } else { + SPIF_SetInstructionPhase(Handle, true, 1, SPIF_CMD_PAGEPROG3ADD); + SPIF_SetAddressPhase(Handle, true, 3, address); + SPIF_SetDummyCycles(Handle, 0); + SPIF_SetDataPhase(Handle, true); + if (SPIF_Transmit(Handle, Data, Size, 1000) == false) { + SPIF_CsPin(Handle, 1); + break; + } + + } + + SPIF_CsPin(Handle, 1); + if (SPIF_WaitForWriting(Handle, 100)) { + dprintf("SPIF_WritePage() %d BYTES WITERN DONE AFTER %ld ms\r\n", (uint16_t)Size, HAL_GetTick() - dbgTime); + retVal = true; + } + + } while (0); + + SPIF_WriteDisable(Handle); + return retVal; +} + +bool SPIF_ReadFn(SPIF_HandleTypeDef *Handle, uint32_t Address, uint8_t *Data, + uint32_t Size) { + bool retVal = false; +// uint8_t tx[5]; + do { +#if SPIF_DEBUG != SPIF_DEBUG_DISABLE + uint32_t dbgTime = HAL_GetTick(); +#endif + dprintf("SPIF_ReadAddress() START ADDRESS %ld\r\n", Address); + SPIF_CsPin(Handle, 0); + if (Handle->BlockCnt >= 512) { + SPIF_SetInstructionPhase(Handle, true, 1, SPIF_CMD_READDATA4ADD); + SPIF_SetAddressPhase(Handle, true, 4, Address); + SPIF_SetDummyCycles(Handle, 0); + SPIF_SetDataPhase(Handle, false); + + } else { + + SPIF_SetInstructionPhase(Handle, true, 1,SPIF_CMD_READDATA3ADD ); + SPIF_SetAddressPhase(Handle, true, 3, Address); + SPIF_SetDummyCycles(Handle, 0); + SPIF_SetDataPhase(Handle, false); + + } + uint16_t max_uint16_size = 0xFFFF - 2; + if (Size > max_uint16_size) { + uint32_t delta = Size; + uint32_t Data_offset = 0; + while (delta > 0) { + if (delta <= max_uint16_size) { + if (SPIF_Receive(Handle, (Data + Data_offset), delta, + 2000) == false) { + SPIF_CsPin(Handle, 1); + break; + } + delta = 0; + } else { + if (SPIF_Receive(Handle, (Data + Data_offset), + max_uint16_size, 2000) == false) { + SPIF_CsPin(Handle, 1); + break; + } + delta = abs(delta - max_uint16_size); + Data_offset += max_uint16_size; + } + } + if (delta > 0) { + //break the main do-while loop, so as to return false + break; + } + } else { + if (SPIF_Receive(Handle, Data, Size, 2000) == false) { + SPIF_CsPin(Handle, 1); + break; + } + } + SPIF_CsPin(Handle, 1); + dprintf("SPIF_ReadAddress() %d BYTES READ DONE AFTER %ld ms\r\n", (uint16_t)Size, HAL_GetTick() - dbgTime); +#if SPIF_DEBUG == SPIF_DEBUG_FULL + dprintf("{\r\n0x%02X", Data[0]); + for (int i = 1; i < Size; i++) + { + if (i % 8 == 0) + { + dprintf("\r\n"); + } + dprintf(", 0x%02X", Data[i]); + } + dprintf("\r\n}\r\n"); +#endif + retVal = true; + + } while (0); + + return retVal; +} + +/** + * @brief Full Erase chip. + * @note Send the Full-Erase-chip command and wait for completion + * + * @param *Handle: Pointer to SPIF_HandleTypeDef structure + * + * @retval bool: true or false + */ +bool SPIF_EraseChip(SPIF_HandleTypeDef *Handle) { + SPIF_Lock(Handle); + bool retVal = false; + uint8_t tx[1] = { 0 }; + do { +#if SPIF_DEBUG != SPIF_DEBUG_DISABLE + uint32_t dbgTime = HAL_GetTick(); +#endif + dprintf("SPIF_EraseChip() START\r\n"); + if (SPIF_WriteEnable(Handle) == false) { + break; + } + SPIF_SetInstructionPhase(Handle, true, 1, SPIF_CMD_CHIPERASE1); + SPIF_SetAddressPhase(Handle, false, 0, 0); + SPIF_SetDummyCycles(Handle, 0); + SPIF_SetDataPhase(Handle, false); + + SPIF_CsPin(Handle, 0); + if (SPIF_Transmit(Handle, tx, 1, 100) == false) { + SPIF_CsPin(Handle, 1); + break; + } + SPIF_CsPin(Handle, 1); + if (SPIF_WaitForWriting(Handle, Handle->BlockCnt * 1000)) { + dprintf("SPIF_EraseChip() DONE AFTER %ld ms\r\n", HAL_GetTick() - dbgTime); + retVal = true; + } + + } while (0); + + SPIF_WriteDisable(Handle); + SPIF_UnLock(Handle); + return retVal; +} + +/** + * @brief Erase Sector. + * @note Send the Erase-Sector command and wait for completion + * + * @param *Handle: Pointer to SPIF_HandleTypeDef structure + * @param Sector: Selected Sector + * + * @retval bool: true or false + */ +bool SPIF_EraseSector(SPIF_HandleTypeDef *Handle, uint32_t Sector) { + SPIF_Lock(Handle); + bool retVal = false; + uint32_t address = Sector * SPIF_SECTOR_SIZE; + uint8_t tx[5]; + do { +#if SPIF_DEBUG != SPIF_DEBUG_DISABLE + uint32_t dbgTime = HAL_GetTick(); +#endif + dprintf("SPIF_EraseSector() START SECTOR %ld\r\n", Sector); + if (Sector >= Handle->SectorCnt) { + dprintf("SPIF_EraseSector() ERROR Sector NUMBER\r\n"); + break; + } + if (SPIF_WriteEnable(Handle) == false) { + break; + } + + if (Handle->BlockCnt >= 512) { + SPIF_SetInstructionPhase(Handle, true, 1,SPIF_CMD_SECTORERASE4ADD ); + SPIF_SetAddressPhase(Handle, true, 4, address); + SPIF_SetDummyCycles(Handle, 0); + SPIF_SetDataPhase(Handle, false); + SPIF_CsPin(Handle, 0); + + if (SPIF_Transmit(Handle, tx, 5, 100) == false) { + SPIF_CsPin(Handle, 1); + break; + } + } else { + SPIF_SetInstructionPhase(Handle, true, 1,SPIF_CMD_SECTORERASE3ADD ); + SPIF_SetAddressPhase(Handle, true, 3, address); + SPIF_SetDummyCycles(Handle, 0); + SPIF_SetDataPhase(Handle, false); + SPIF_CsPin(Handle, 0); + + if (SPIF_Transmit(Handle, tx, 4, 100) == false) { + SPIF_CsPin(Handle, 1); + break; + } + } + SPIF_CsPin(Handle, 1); + if (SPIF_WaitForWriting(Handle, 1000)) { + dprintf("SPIF_EraseSector() DONE AFTER %ld ms\r\n", HAL_GetTick() - dbgTime); + retVal = true; + } + + } while (0); + + SPIF_WriteDisable(Handle); + SPIF_UnLock(Handle); + return retVal; +} + +/* + * @brief Write QPI Enable command + * @note Send the QPI-Enable command + * + * @param *Handle: Pointer to SPIF_HandleTypeDef structure + * @retval bool: true or false + */ +bool SPIF_QPI_Enable(SPIF_HandleTypeDef *Handle) { + bool retVal = true; + uint8_t tx[1] = { SPIF_CMD_ENTERQPI }; + + SPIF_SetInstructionPhase(Handle, true, 1,SPIF_CMD_ENTERQPI ); + SPIF_SetAddressPhase(Handle, false, 0, 0); + SPIF_SetDummyCycles(Handle, 0); + SPIF_SetDataPhase(Handle, false); + + SPIF_CsPin(Handle, 0); + + if (SPIF_Transmit(Handle, tx, 1, 100) == false) { + retVal = false; + dprintf("SPIF_IS25_QPI_Enable() Error\r\n"); + } + SPIF_CsPin(Handle, 1); + return retVal; +} + +/** + * @brief Erase 32K Block. + * @note Send the Erase-Block command and wait for completion + * + * @param *Handle: Pointer to SPIF_HandleTypeDef structure + * @param Sector: Selected Block + * + * @retval bool: true or false + */ +bool SPIF_EraseBlock(SPIF_HandleTypeDef *Handle, uint32_t Block) { + SPIF_Lock(Handle); + bool retVal = false; + uint32_t address = Block * SPIF_BLOCK_SIZE; + uint8_t tx[5]; + do { +#if SPIF_DEBUG != SPIF_DEBUG_DISABLE + uint32_t dbgTime = HAL_GetTick(); +#endif + dprintf("SPIF_EraseBlock() START PAGE %ld\r\n", Block); + if (Block >= Handle->BlockCnt) { + dprintf("SPIF_EraseBlock() ERROR Block NUMBER\r\n"); + break; + } + if (SPIF_WriteEnable(Handle) == false) { + break; + } + SPIF_CsPin(Handle, 0); + if (Handle->BlockCnt >= 512) { + SPIF_SetInstructionPhase(Handle, true, 1,SPIF_CMD_BLOCKERASE32K4ADD ); + SPIF_SetAddressPhase(Handle, true, 4, address); + SPIF_SetDummyCycles(Handle, 0); + SPIF_SetDataPhase(Handle, false); + SPIF_CsPin(Handle, 0); + + if (SPIF_Transmit(Handle, tx, 5, 100) == false) { + SPIF_CsPin(Handle, 1); + break; + } + } else { + SPIF_SetInstructionPhase(Handle, true, 1,SPIF_CMD_BLOCKERASE32K3ADD ); + SPIF_SetAddressPhase(Handle, true, 3, address); + SPIF_SetDummyCycles(Handle, 0); + SPIF_SetDataPhase(Handle, false); + + if (SPIF_Transmit(Handle, tx, 4, 100) == false) { + SPIF_CsPin(Handle, 1); + break; + } + } + SPIF_CsPin(Handle, 1); + if (SPIF_WaitForWriting(Handle, 3000)) { + dprintf("SPIF_EraseBlock() DONE AFTER %ld ms\r\n", HAL_GetTick() - dbgTime); + retVal = true; + } + + } while (0); + + SPIF_WriteDisable(Handle); + SPIF_UnLock(Handle); + return retVal; +} + +/** + * @brief Erase 64K Block. + * @note Send the Erase-Block command and wait for completion + * + * @param *Handle: Pointer to SPIF_HandleTypeDef structure + * @param Sector: Selected Block + * + * @retval bool: true or false + */ +bool SPIF_EraseBlock_64K(SPIF_HandleTypeDef *Handle, uint32_t Block) { + //to be implemented + __NOP(); + return false; +} + +bool SPIF_FindChip(SPIF_HandleTypeDef *Handle) { +// uint8_t tx[4] = { SPIF_CMD_JEDECID, 0xFF, 0xFF, 0xFF }; + uint8_t rx[4]; + bool retVal = false; + do { + dprintf("SPIF_FindChip()\r\n"); + SPIF_SetInstructionPhase(Handle, true, 1,SPIF_CMD_JEDECID ); + SPIF_SetAddressPhase(Handle, false, 0, 0); + SPIF_SetDummyCycles(Handle, 3); + SPIF_SetDataPhase(Handle, false); + + SPIF_CsPin(Handle, 0); + if (SPIF_Receive(Handle, rx, 4, 100) == false) { + SPIF_CsPin(Handle, 1); + break; + } + SPIF_CsPin(Handle, 1); + dprintf("CHIP ID: 0x%02X%02X%02X\r\n", rx[1], rx[2], rx[3]); + Handle->Manufactor = rx[1]; + Handle->MemType = rx[2]; + Handle->Size = rx[3]; + + dprintf(" - SIZE: "); + switch (Handle->Size) { + case SPIF_SIZE_1MBIT: + Handle->BlockCnt = 2; + dprintf("1 MBIT\r\n"); + break; + case SPIF_SIZE_2MBIT: + Handle->BlockCnt = 4; + dprintf("2 MBIT\r\n"); + break; + case SPIF_SIZE_4MBIT: + Handle->BlockCnt = 8; + dprintf("4 MBIT\r\n"); + break; + case SPIF_SIZE_8MBIT: + Handle->BlockCnt = 16; + dprintf("8 MBIT\r\n"); + break; + case SPIF_SIZE_16MBIT: + Handle->BlockCnt = 32; + dprintf("16 MBIT\r\n"); + break; + case SPIF_SIZE_32MBIT: + Handle->BlockCnt = 64; + dprintf("32 MBIT\r\n"); + break; + case SPIF_SIZE_64MBIT: + Handle->BlockCnt = 128; + dprintf("64 MBIT\r\n"); + break; + case SPIF_SIZE_128MBIT: + Handle->BlockCnt = 256; + dprintf("128 MBIT\r\n"); + break; + case SPIF_SIZE_256MBIT: + Handle->BlockCnt = 512; + dprintf("256 MBIT\r\n"); + break; + case SPIF_SIZE_512MBIT: + Handle->BlockCnt = 1024; + dprintf("512 MBIT\r\n"); + break; + default: + Handle->Size = SPIF_SIZE_ERROR; + dprintf("ERROR\r\n"); + break; + } + + Handle->SectorCnt = Handle->BlockCnt * 16; + Handle->PageCnt = (Handle->SectorCnt * SPIF_SECTOR_SIZE) + / SPIF_PAGE_SIZE; + dprintf("SPIF BLOCK CNT: %ld\r\n", Handle->BlockCnt); dprintf("SPIF SECTOR CNT: %ld\r\n", Handle->SectorCnt); dprintf("SPIF PAGE CNT: %ld\r\n", Handle->PageCnt); dprintf("SPIF STATUS1: 0x%02X\r\n", SPIF_ReadReg1(Handle)); +// dprintf("SPIF STATUS2: 0x%02X\r\n", SPIF_ReadReg2(Handle)); +// dprintf("SPIF STATUS3: 0x%02X\r\n", SPIF_ReadReg3(Handle)); + retVal = true; + + } while (0); + + return retVal; +} + +#endif diff --git a/spif_compat_is25xx.h b/spif_compat_is25xx.h new file mode 100644 index 0000000..2a87a07 --- /dev/null +++ b/spif_compat_is25xx.h @@ -0,0 +1,24 @@ +#ifndef _SPIF_COMPAT_IS25_H_ +#define _SPIF_COMPAT_IS25_H_ + +#include "spif_common.h" +#include "spif_internal.h" +#include + + +// IS25-specific function prototypes +bool SPIF_WriteEnable(SPIF_HandleTypeDef *Handle); +bool SPIF_WriteDisable(SPIF_HandleTypeDef *Handle); +bool SPIF_WaitForWriting(SPIF_HandleTypeDef *Handle, uint32_t Timeout); +uint8_t SPIF_ReadReg1(SPIF_HandleTypeDef *Handle); +bool SPIF_WriteReg1(SPIF_HandleTypeDef *Handle, uint8_t Data); +bool SPIF_WriteFn(SPIF_HandleTypeDef *Handle, uint32_t PageNumber, uint8_t *Data, uint32_t Size, uint32_t Offset); +bool SPIF_ReadFn(SPIF_HandleTypeDef *Handle, uint32_t Address, uint8_t *Data, uint32_t Size); +bool SPIF_EraseChip(SPIF_HandleTypeDef *Handle); +bool SPIF_EraseSector(SPIF_HandleTypeDef *Handle, uint32_t Sector); +bool SPIF_QPI_Enable(SPIF_HandleTypeDef *Handle); +bool SPIF_EraseBlock(SPIF_HandleTypeDef *Handle, uint32_t Block); +bool SPIF_EraseBlock_64K(SPIF_HandleTypeDef *Handle, uint32_t Block); +bool SPIF_FindChip(SPIF_HandleTypeDef *Handle); + +#endif diff --git a/spif_compat_w25xx.c b/spif_compat_w25xx.c new file mode 100644 index 0000000..70840e2 --- /dev/null +++ b/spif_compat_w25xx.c @@ -0,0 +1,849 @@ + +#include "spif_compat_w25xx.h" +#include "spif.h" + +#if (SPIF_COMPAT == SPIF_COMPAT_W25XX) + +/*Register Definition for W25XX*/ +#define SPIF_DUMMY_BYTE 0xA5 + +#define SPIF_CMD_READSFDP 0x5A +#define SPIF_CMD_ID 0x90 +#define SPIF_CMD_JEDECID 0x9F +#define SPIF_CMD_UNIQUEID 0x4B +#define SPIF_CMD_WRITEDISABLE 0x04 +#define SPIF_CMD_READSTATUS1 0x05 +#define SPIF_CMD_READSTATUS2 0x35 +#define SPIF_CMD_READSTATUS3 0x15 +#define SPIF_CMD_WRITESTATUSEN 0x50 +#define SPIF_CMD_WRITESTATUS1 0x01 +#define SPIF_CMD_WRITESTATUS2 0x31 +#define SPIF_CMD_WRITESTATUS3 0x11 +#define SPIF_CMD_WRITEENABLE 0x06 +#define SPIF_CMD_ADDR4BYTE_EN 0xB7 +#define SPIF_CMD_ADDR4BYTE_DIS 0xE9 +#define SPIF_CMD_PAGEPROG3ADD 0x02 +#define SPIF_CMD_PAGEPROG4ADD 0x12 +#define SPIF_CMD_READDATA3ADD 0x03 +#define SPIF_CMD_READDATA4ADD 0x13 +#define SPIF_CMD_FASTREAD3ADD 0x0B +#define SPIF_CMD_FASTREAD4ADD 0x0C +#define SPIF_CMD_SECTORERASE3ADD 0x20 +#define SPIF_CMD_SECTORERASE4ADD 0x21 +#define SPIF_CMD_BLOCKERASE3ADD 0xD8 +#define SPIF_CMD_BLOCKERASE4ADD 0xDC +#define SPIF_CMD_CHIPERASE1 0x60 +#define SPIF_CMD_CHIPERASE2 0xC7 +#define SPIF_CMD_SUSPEND 0x75 +#define SPIF_CMD_RESUME 0x7A +#define SPIF_CMD_POWERDOWN 0xB9 +#define SPIF_CMD_RELEASE 0xAB +#define SPIF_CMD_FRAMSERNO 0xC3 + +#define SPIF_STATUS1_BUSY (1 << 0) +#define SPIF_STATUS1_WEL (1 << 1) +#define SPIF_STATUS1_BP0 (1 << 2) +#define SPIF_STATUS1_BP1 (1 << 3) +#define SPIF_STATUS1_BP2 (1 << 4) +#define SPIF_STATUS1_TP (1 << 5) +#define SPIF_STATUS1_SEC (1 << 6) +#define SPIF_STATUS1_SRP0 (1 << 7) + +#define SPIF_STATUS2_SRP1 (1 << 0) +#define SPIF_STATUS2_QE (1 << 1) +#define SPIF_STATUS2_RESERVE1 (1 << 2) +#define SPIF_STATUS2_LB0 (1 << 3) +#define SPIF_STATUS2_LB1 (1 << 4) +#define SPIF_STATUS2_LB2 (1 << 5) +#define SPIF_STATUS2_CMP (1 << 6) +#define SPIF_STATUS2_SUS (1 << 7) + +#define SPIF_STATUS3_RESERVE1 (1 << 0) +#define SPIF_STATUS3_RESERVE2 (1 << 1) +#define SPIF_STATUS3_WPS (1 << 2) +#define SPIF_STATUS3_RESERVE3 (1 << 3) +#define SPIF_STATUS3_RESERVE4 (1 << 4) +#define SPIF_STATUS3_DRV0 (1 << 5) +#define SPIF_STATUS3_DRV1 (1 << 6) +#define SPIF_STATUS3_HOLD (1 << 7) + + + +bool SPIF_WriteEnable(SPIF_HandleTypeDef *Handle) +{ + bool retVal = true; + uint8_t tx[1] = {SPIF_CMD_WRITEENABLE}; + SPIF_SetInstructionPhase(Handle, true, 1, SPIF_CMD_WRITEENABLE); + SPIF_SetAddressPhase(Handle, false, 0, 0); + SPIF_SetDummyCycles(Handle, 0); + SPIF_SetDataPhase(Handle, false); + + SPIF_CsPin(Handle, 0); + if (SPIF_Transmit(Handle, tx, 1, 100) == false) + { + retVal = false; + dprintf("SPIF_WriteEnable() Error\r\n"); + } + SPIF_CsPin(Handle, 1); + return retVal; +} + + +bool SPIF_WriteDisable(SPIF_HandleTypeDef *Handle) +{ + bool retVal = true; + uint8_t tx[1] = {SPIF_CMD_WRITEDISABLE}; + SPIF_SetInstructionPhase(Handle, true, 1, SPIF_CMD_WRITEDISABLE); + SPIF_SetAddressPhase(Handle, false, 0, 0); + SPIF_SetDummyCycles(Handle, 0); + SPIF_SetDataPhase(Handle, false); + SPIF_CsPin(Handle, 0); + if (SPIF_Transmit(Handle, tx, 1, 100) == false) + { + retVal = false; + dprintf("SPIF_WriteDisable() Error\r\n"); + } + SPIF_CsPin(Handle, 1); + return retVal; +} + + +bool SPIF_WaitForWriting(SPIF_HandleTypeDef *Handle, uint32_t Timeout) +{ + bool retVal = false; + uint32_t startTime = HAL_GetTick(); + while (1) + { + SPIF_Delay(1); + if (HAL_GetTick() - startTime >= Timeout) + { + dprintf("SPIF_WaitForWriting() TIMEOUT\r\n"); + break; + } + if ((SPIF_ReadReg1(Handle) & SPIF_STATUS1_BUSY) == 0) + + { + retVal = true; + break; + } + } + return retVal; +} + + + +// This reads status register 1 for SPIF_COMPAT_W25XX +// This will also read the only status register for SPIF_COMPAT_IS25XX +uint8_t SPIF_ReadReg1(SPIF_HandleTypeDef *Handle) +{ + uint8_t retVal = 0; +// uint8_t tx[2] = {SPIF_CMD_READSTATUS1, SPIF_DUMMY_BYTE}; + uint8_t rx[2]; + SPIF_SetInstructionPhase(Handle, true, 1, SPIF_CMD_READSTATUS1); + SPIF_SetAddressPhase(Handle, false, 0, 0); + SPIF_SetDummyCycles(Handle, 1); + SPIF_SetDataPhase(Handle, false); + SPIF_CsPin(Handle, 0); + if (SPIF_Receive(Handle, rx, 2, 100) == true) + { + retVal = rx[1]; + } + SPIF_CsPin(Handle, 1); + return retVal; +} + +/***********************************************************************************************************/ + +uint8_t SPIF_ReadReg2(SPIF_HandleTypeDef *Handle) +{ + + uint8_t retVal = 0; +// uint8_t tx[2] = {SPIF_CMD_READSTATUS2, SPIF_DUMMY_BYTE}; + uint8_t rx[2]; + SPIF_SetInstructionPhase(Handle, true, 1, SPIF_CMD_READSTATUS2); + SPIF_SetAddressPhase(Handle, false, 0, 0); + SPIF_SetDummyCycles(Handle, 1); + SPIF_SetDataPhase(Handle, false); + SPIF_CsPin(Handle, 0); + if (SPIF_Receive(Handle, rx, 2, 100) == true) + { + retVal = rx[1]; + } + SPIF_CsPin(Handle, 1); + return retVal; +} + + +uint8_t SPIF_ReadReg3(SPIF_HandleTypeDef *Handle) +{ + + uint8_t retVal = 0; +// uint8_t tx[2] = {SPIF_CMD_READSTATUS3, SPIF_DUMMY_BYTE}; + uint8_t rx[2]; + SPIF_SetInstructionPhase(Handle, true, 1, SPIF_CMD_READSTATUS3); + SPIF_SetAddressPhase(Handle, false, 0, 0); + SPIF_SetDummyCycles(Handle, 1); + SPIF_SetDataPhase(Handle, false); + SPIF_CsPin(Handle, 0); + if (SPIF_Receive(Handle, rx, 2, 100) == true) + { + retVal = rx[1]; + } + SPIF_CsPin(Handle, 1); + return retVal; + +} + + +bool SPIF_WriteReg1(SPIF_HandleTypeDef *Handle, uint8_t Data) +{ + bool retVal = true; + uint8_t tx[1] = { Data}; + + uint8_t cmd = SPIF_CMD_WRITESTATUSEN; + + do + { + SPIF_SetInstructionPhase(Handle, true, 1, SPIF_CMD_WRITESTATUSEN); + SPIF_SetAddressPhase(Handle, false, 0, 0); + SPIF_SetDummyCycles(Handle, 0); + SPIF_SetDataPhase(Handle, false); + + SPIF_CsPin(Handle, 0); + if (SPIF_Transmit(Handle, &cmd, 1, 100) == false) + { + retVal = false; + SPIF_CsPin(Handle, 1); + break; + } + SPIF_CsPin(Handle, 1); + + SPIF_SetInstructionPhase(Handle, true, 1, SPIF_CMD_WRITESTATUS1); + SPIF_SetAddressPhase(Handle, false, 0, 0); + SPIF_SetDummyCycles(Handle, 0); + SPIF_SetDataPhase(Handle, true); + + SPIF_CsPin(Handle, 0); + if (SPIF_Transmit(Handle, tx, 1, 100) == false) + { + retVal = false; + SPIF_CsPin(Handle, 1); + break; + } + SPIF_CsPin(Handle, 1); + } while (0); + + return retVal; +} + + +bool SPIF_WriteReg2(SPIF_HandleTypeDef *Handle, uint8_t Data) +{ + + bool retVal = true; + uint8_t tx[1] = { Data}; + uint8_t cmd = SPIF_CMD_WRITESTATUSEN; + do + { + SPIF_SetInstructionPhase(Handle, true, 1, SPIF_CMD_WRITESTATUSEN); + SPIF_SetAddressPhase(Handle, false, 0, 0); + SPIF_SetDummyCycles(Handle, 0); + SPIF_SetDataPhase(Handle, false); + + SPIF_CsPin(Handle, 0); + if (SPIF_Transmit(Handle, &cmd, 1, 100) == false) + { + retVal = false; + SPIF_CsPin(Handle, 1); + break; + } + SPIF_CsPin(Handle, 1); + + SPIF_SetInstructionPhase(Handle, true, 1, SPIF_CMD_WRITESTATUS2); + SPIF_SetAddressPhase(Handle, false, 0, 0); + SPIF_SetDummyCycles(Handle, 0); + SPIF_SetDataPhase(Handle, true); + + SPIF_CsPin(Handle, 0); + if (SPIF_Transmit(Handle, tx, 1, 100) == false) + { + retVal = false; + SPIF_CsPin(Handle, 1); + break; + } + SPIF_CsPin(Handle, 1); + } while (0); + + return retVal; +} + + +bool SPIF_WriteReg3(SPIF_HandleTypeDef *Handle, uint8_t Data) +{ + + bool retVal = true; + uint8_t tx[1] = { Data}; + uint8_t cmd = SPIF_CMD_WRITESTATUSEN; + do + { + SPIF_SetInstructionPhase(Handle, true, 1, SPIF_CMD_WRITESTATUSEN); + SPIF_SetAddressPhase(Handle, false, 0, 0); + SPIF_SetDummyCycles(Handle, 0); + SPIF_SetDataPhase(Handle, false); + + SPIF_CsPin(Handle, 0); + if (SPIF_Transmit(Handle, &cmd, 1, 100) == false) + { + retVal = false; + SPIF_CsPin(Handle, 1); + break; + } + SPIF_CsPin(Handle, 1); + + SPIF_SetInstructionPhase(Handle, true, 1, SPIF_CMD_WRITESTATUS3); + SPIF_SetAddressPhase(Handle, false, 0, 0); + SPIF_SetDummyCycles(Handle, 0); + SPIF_SetDataPhase(Handle, true); + + SPIF_CsPin(Handle, 0); + if (SPIF_Transmit(Handle, tx, 1, 100) == false) + { + retVal = false; + SPIF_CsPin(Handle, 1); + break; + } + SPIF_CsPin(Handle, 1); + } while (0); + + return retVal; + +} + + +bool SPIF_WriteFn(SPIF_HandleTypeDef *Handle, uint32_t PageNumber, uint8_t *Data, uint32_t Size, uint32_t Offset) +{ + bool retVal = false; + uint32_t address = 0, maximum = SPIF_PAGE_SIZE - Offset; +// uint8_t tx[5]; + do + { +#if SPIF_DEBUG != SPIF_DEBUG_DISABLE + uint32_t dbgTime = HAL_GetTick(); +#endif + dprintf("SPIF_WritePage() START PAGE %ld\r\n", PageNumber); + if (PageNumber >= Handle->PageCnt) + { + dprintf("SPIF_WritePage() ERROR PageNumber\r\n"); + break; + } + if (Offset >= SPIF_PAGE_SIZE) + { + dprintf("SPIF_WritePage() ERROR Offset\r\n"); + break; + } + if (Size > maximum) + { + Size = maximum; + } + address = SPIF_PageToAddress(PageNumber) + Offset; +#if SPIF_DEBUG == SPIF_DEBUG_FULL + dprintf("SPIF WRITING {\r\n0x%02X", Data[0]); + for (int i = 1; i < Size; i++) + { + if (i % 8 == 0) + { + dprintf("\r\n"); + } + dprintf(", 0x%02X", Data[i]); + } + dprintf("\r\n}\r\n"); +#endif + if (SPIF_WriteEnable(Handle) == false) + { + break; + } + SPIF_CsPin(Handle, 0); + if (Handle->BlockCnt >= 512) + { + SPIF_SetInstructionPhase(Handle, true, 1, SPIF_CMD_PAGEPROG4ADD); + SPIF_SetAddressPhase(Handle, true, 4, address); + SPIF_SetDummyCycles(Handle, 0); + SPIF_SetDataPhase(Handle, true); + + + + + } + else + { + SPIF_SetInstructionPhase(Handle, true, 1,SPIF_CMD_PAGEPROG3ADD ); + SPIF_SetAddressPhase(Handle, true, 3, address); + SPIF_SetDummyCycles(Handle, 0); + SPIF_SetDataPhase(Handle, true); + + + } + if (SPIF_Transmit(Handle, Data, Size, 1000) == false) + { + SPIF_CsPin(Handle, 1); + break; + } + SPIF_CsPin(Handle, 1); + if (SPIF_WaitForWriting(Handle, 100)) + { + dprintf("SPIF_WritePage() %d BYTES WITERN DONE AFTER %ld ms\r\n", (uint16_t)Size, HAL_GetTick() - dbgTime); + retVal = true; + } + + } while (0); + + SPIF_WriteDisable(Handle); + return retVal; +} + + + +bool SPIF_ReadFn(SPIF_HandleTypeDef *Handle, uint32_t Address, uint8_t *Data, uint32_t Size) +{ + bool retVal = false; +// uint8_t tx[5]; + do + { +#if SPIF_DEBUG != SPIF_DEBUG_DISABLE + uint32_t dbgTime = HAL_GetTick(); +#endif + dprintf("SPIF_ReadAddress() START ADDRESS %ld\r\n", Address); + SPIF_CsPin(Handle, 0); + if (Handle->BlockCnt >= 512) + { + SPIF_SetInstructionPhase(Handle, true, 1, SPIF_CMD_READDATA4ADD); + SPIF_SetAddressPhase(Handle, true, 4, Address); + SPIF_SetDummyCycles(Handle, 0); + SPIF_SetDataPhase(Handle, false); + + + } + else + { + SPIF_SetInstructionPhase(Handle, true, 1, SPIF_CMD_READDATA3ADD); + SPIF_SetAddressPhase(Handle, true, 3, Address); + SPIF_SetDummyCycles(Handle, 0); + SPIF_SetDataPhase(Handle, false); + + + } + uint16_t max_uint16_size = 0xFFFF - 2; + if(Size > max_uint16_size) + { + uint32_t delta = Size; + uint32_t Data_offset = 0; + while(delta > 0) + { + if(delta <= max_uint16_size) + { + if (SPIF_Receive(Handle, (Data+Data_offset), delta, 2000) == false) + { + SPIF_CsPin(Handle, 1); + break; + } + delta = 0; + } + else + { + if (SPIF_Receive(Handle, (Data+Data_offset), max_uint16_size, 2000) == false) + { + SPIF_CsPin(Handle, 1); + break; + } + delta = abs(delta - max_uint16_size); + Data_offset += max_uint16_size; + } + } + if(delta > 0) + { + //break the main do-while loop, so as to return false + break; + } + } + else + { + if(SPIF_Receive(Handle, Data, Size, 2000) == false) + { + SPIF_CsPin(Handle, 1); + break; + } + } + SPIF_CsPin(Handle, 1); + dprintf("SPIF_ReadAddress() %d BYTES READ DONE AFTER %ld ms\r\n", (uint16_t)Size, HAL_GetTick() - dbgTime); +#if SPIF_DEBUG == SPIF_DEBUG_FULL + dprintf("{\r\n0x%02X", Data[0]); + for (int i = 1; i < Size; i++) + { + if (i % 8 == 0) + { + dprintf("\r\n"); + } + dprintf(", 0x%02X", Data[i]); + } + dprintf("\r\n}\r\n"); +#endif + retVal = true; + + } while (0); + + return retVal; +} + + + +/** + * @brief Full Erase chip. + * @note Send the Full-Erase-chip command and wait for completion + * + * @param *Handle: Pointer to SPIF_HandleTypeDef structure + * + * @retval bool: true or false + */ +bool SPIF_EraseChip(SPIF_HandleTypeDef *Handle) +{ + SPIF_Lock(Handle); + bool retVal = false; + uint8_t tx[1] = {SPIF_CMD_CHIPERASE1}; + do + { +#if SPIF_DEBUG != SPIF_DEBUG_DISABLE + uint32_t dbgTime = HAL_GetTick(); +#endif + dprintf("SPIF_EraseChip() START\r\n"); + if (SPIF_WriteEnable(Handle) == false) + { + break; + } + SPIF_SetInstructionPhase(Handle, true, 1, SPIF_CMD_CHIPERASE1); + SPIF_SetAddressPhase(Handle, false, 0, 0); + SPIF_SetDummyCycles(Handle, 0); + SPIF_SetDataPhase(Handle, false); + + SPIF_CsPin(Handle, 0); + if (SPIF_Transmit(Handle, tx, 1, 100) == false) + { + SPIF_CsPin(Handle, 1); + break; + } + SPIF_CsPin(Handle, 1); + if (SPIF_WaitForWriting(Handle, Handle->BlockCnt * 1000)) + { + dprintf("SPIF_EraseChip() DONE AFTER %ld ms\r\n", HAL_GetTick() - dbgTime); + retVal = true; + } + + } while (0); + + SPIF_WriteDisable(Handle); + SPIF_UnLock(Handle); + return retVal; +} + + +/** + * @brief Erase Sector. + * @note Send the Erase-Sector command and wait for completion + * + * @param *Handle: Pointer to SPIF_HandleTypeDef structure + * @param Sector: Selected Sector + * + * @retval bool: true or false + */ +bool SPIF_EraseSector(SPIF_HandleTypeDef *Handle, uint32_t Sector) +{ + SPIF_Lock(Handle); + bool retVal = false; + uint32_t address = Sector * SPIF_SECTOR_SIZE; + uint8_t tx[5]; + do + { +#if SPIF_DEBUG != SPIF_DEBUG_DISABLE + uint32_t dbgTime = HAL_GetTick(); +#endif + dprintf("SPIF_EraseSector() START SECTOR %ld\r\n", Sector); + if (Sector >= Handle->SectorCnt) + { + dprintf("SPIF_EraseSector() ERROR Sector NUMBER\r\n"); + break; + } + if (SPIF_WriteEnable(Handle) == false) + { + break; + } + SPIF_CsPin(Handle, 0); + if (Handle->BlockCnt >= 512) + { + SPIF_SetInstructionPhase(Handle, true, 1, SPIF_CMD_SECTORERASE4ADD); + SPIF_SetAddressPhase(Handle, true, 4, address); + SPIF_SetDummyCycles(Handle, 0); + SPIF_SetDataPhase(Handle, false); + + if (SPIF_Transmit(Handle, tx, 5, 100) == false) + { + SPIF_CsPin(Handle, 1); + break; + } + } + else + { + SPIF_SetInstructionPhase(Handle, true, 1, SPIF_CMD_SECTORERASE3ADD); + SPIF_SetAddressPhase(Handle, true, 3, address); + SPIF_SetDummyCycles(Handle, 0); + SPIF_SetDataPhase(Handle, false); + tx[0] = SPIF_CMD_SECTORERASE3ADD; + tx[1] = (address & 0x00FF0000) >> 16; + tx[2] = (address & 0x0000FF00) >> 8; + tx[3] = (address & 0x000000FF); + if (SPIF_Transmit(Handle, tx, 4, 100) == false) + { + SPIF_CsPin(Handle, 1); + break; + } + } + SPIF_CsPin(Handle, 1); + if (SPIF_WaitForWriting(Handle, 1000)) + { + dprintf("SPIF_EraseSector() DONE AFTER %ld ms\r\n", HAL_GetTick() - dbgTime); + retVal = true; + } + + } while (0); + + SPIF_WriteDisable(Handle); + SPIF_UnLock(Handle); + return retVal; +} + + + +/** + * @brief Erase Block. + * @note Send the Erase-Block command and wait for completion + * + * @param *Handle: Pointer to SPIF_HandleTypeDef structure + * @param Sector: Selected Block + * + * @retval bool: true or false + */ +bool SPIF_EraseBlock(SPIF_HandleTypeDef *Handle, uint32_t Block) +{ + SPIF_Lock(Handle); + bool retVal = false; + uint32_t address = Block * SPIF_BLOCK_SIZE; + uint8_t tx[5]; + do + { +#if SPIF_DEBUG != SPIF_DEBUG_DISABLE + uint32_t dbgTime = HAL_GetTick(); +#endif + dprintf("SPIF_EraseBlock() START PAGE %ld\r\n", Block); + if (Block >= Handle->BlockCnt) + { + dprintf("SPIF_EraseBlock() ERROR Block NUMBER\r\n"); + break; + } + if (SPIF_WriteEnable(Handle) == false) + { + break; + } + SPIF_CsPin(Handle, 0); + if (Handle->BlockCnt >= 512) + { + SPIF_SetInstructionPhase(Handle, true, 1, SPIF_CMD_BLOCKERASE4ADD); + SPIF_SetAddressPhase(Handle, true, 4, address); + SPIF_SetDummyCycles(Handle, 0); + SPIF_SetDataPhase(Handle, false); + + + if (SPIF_Transmit(Handle, tx, 5, 100) == false) + { + SPIF_CsPin(Handle, 1); + break; + } + } + else + { + SPIF_SetInstructionPhase(Handle, true, 1, SPIF_CMD_BLOCKERASE3ADD); + SPIF_SetAddressPhase(Handle, true, 3, address); + SPIF_SetDummyCycles(Handle, 0); + SPIF_SetDataPhase(Handle, false); + + tx[0] = SPIF_CMD_BLOCKERASE3ADD; + tx[1] = (address & 0x00FF0000) >> 16; + tx[2] = (address & 0x0000FF00) >> 8; + tx[3] = (address & 0x000000FF); + if (SPIF_Transmit(Handle, tx, 4, 100) == false) + { + SPIF_CsPin(Handle, 1); + break; + } + } + SPIF_CsPin(Handle, 1); + if (SPIF_WaitForWriting(Handle, 3000)) + { + dprintf("SPIF_EraseBlock() DONE AFTER %ld ms\r\n", HAL_GetTick() - dbgTime); + retVal = true; + } + + } while (0); + + SPIF_WriteDisable(Handle); + SPIF_UnLock(Handle); + return retVal; +} + + +/***********************************************************************************************************/ + +bool SPIF_FindChip(SPIF_HandleTypeDef *Handle) +{ +// uint8_t tx[4] = {SPIF_CMD_JEDECID, 0xFF, 0xFF, 0xFF}; + uint8_t rx[4]; + bool retVal = false; + do + { + dprintf("SPIF_FindChip()\r\n"); + SPIF_SetInstructionPhase(Handle, true, 1, SPIF_CMD_JEDECID); + SPIF_SetAddressPhase(Handle, false, 0, 0); + SPIF_SetDummyCycles(Handle, 3); + SPIF_SetDataPhase(Handle, false); + + SPIF_CsPin(Handle, 0); + if (SPIF_Receive(Handle, rx, 4, 100) == false) + { + SPIF_CsPin(Handle, 1); + break; + } + SPIF_CsPin(Handle, 1); + dprintf("CHIP ID: 0x%02X%02X%02X\r\n", rx[1], rx[2], rx[3]); + Handle->Manufactor = rx[1]; + Handle->MemType = rx[2]; + Handle->Size = rx[3]; + + dprintf("SPIF MANUFACTURE: "); + switch (Handle->Manufactor) + { + case SPIF_MANUFACTOR_WINBOND: + dprintf("WINBOND"); + break; + case SPIF_MANUFACTOR_SPANSION: + dprintf("SPANSION"); + break; + case SPIF_MANUFACTOR_MICRON: + dprintf("MICRON"); + break; + case SPIF_MANUFACTOR_MACRONIX: + dprintf("MACRONIX"); + break; + case SPIF_MANUFACTOR_ISSI: + dprintf("ISSI"); + break; + case SPIF_MANUFACTOR_GIGADEVICE: + dprintf("GIGADEVICE"); + break; + case SPIF_MANUFACTOR_AMIC: + dprintf("AMIC"); + break; + case SPIF_MANUFACTOR_SST: + dprintf("SST"); + break; + case SPIF_MANUFACTOR_HYUNDAI: + dprintf("HYUNDAI"); + break; + case SPIF_MANUFACTOR_FUDAN: + dprintf("FUDAN"); + break; + case SPIF_MANUFACTOR_ESMT: + dprintf("ESMT"); + break; + case SPIF_MANUFACTOR_INTEL: + dprintf("INTEL"); + break; + case SPIF_MANUFACTOR_SANYO: + dprintf("SANYO"); + break; + case SPIF_MANUFACTOR_FUJITSU: + dprintf("FUJITSU"); + break; + case SPIF_MANUFACTOR_EON: + dprintf("EON"); + break; + case SPIF_MANUFACTOR_PUYA: + dprintf("PUYA"); + break; + default: + Handle->Manufactor = SPIF_MANUFACTOR_ERROR; + dprintf("ERROR"); + break; + } + dprintf(" - MEMTYPE: 0x%02X", Handle->MemType); + dprintf(" - SIZE: "); + switch (Handle->Size) + { + case SPIF_SIZE_1MBIT: + Handle->BlockCnt = 2; + dprintf("1 MBIT\r\n"); + break; + case SPIF_SIZE_2MBIT: + Handle->BlockCnt = 4; + dprintf("2 MBIT\r\n"); + break; + case SPIF_SIZE_4MBIT: + Handle->BlockCnt = 8; + dprintf("4 MBIT\r\n"); + break; + case SPIF_SIZE_8MBIT: + Handle->BlockCnt = 16; + dprintf("8 MBIT\r\n"); + break; + case SPIF_SIZE_16MBIT: + Handle->BlockCnt = 32; + dprintf("16 MBIT\r\n"); + break; + case SPIF_SIZE_32MBIT: + Handle->BlockCnt = 64; + dprintf("32 MBIT\r\n"); + break; + case SPIF_SIZE_64MBIT: + Handle->BlockCnt = 128; + dprintf("64 MBIT\r\n"); + break; + case SPIF_SIZE_128MBIT: + Handle->BlockCnt = 256; + dprintf("128 MBIT\r\n"); + break; + case SPIF_SIZE_256MBIT: + Handle->BlockCnt = 512; + dprintf("256 MBIT\r\n"); + break; + case SPIF_SIZE_512MBIT: + Handle->BlockCnt = 1024; + dprintf("512 MBIT\r\n"); + break; + default: + Handle->Size = SPIF_SIZE_ERROR; + dprintf("ERROR\r\n"); + break; + } + + Handle->SectorCnt = Handle->BlockCnt * 16; + Handle->PageCnt = (Handle->SectorCnt * SPIF_SECTOR_SIZE) / SPIF_PAGE_SIZE; + dprintf("SPIF BLOCK CNT: %ld\r\n", Handle->BlockCnt); + dprintf("SPIF SECTOR CNT: %ld\r\n", Handle->SectorCnt); + dprintf("SPIF PAGE CNT: %ld\r\n", Handle->PageCnt); + dprintf("SPIF STATUS1: 0x%02X\r\n", SPIF_ReadReg1(Handle)); + dprintf("SPIF STATUS2: 0x%02X\r\n", SPIF_ReadReg2(Handle)); + dprintf("SPIF STATUS3: 0x%02X\r\n", SPIF_ReadReg3(Handle)); + retVal = true; + + } while (0); + + return retVal; +} + +#endif diff --git a/spif_compat_w25xx.h b/spif_compat_w25xx.h new file mode 100644 index 0000000..0b87bac --- /dev/null +++ b/spif_compat_w25xx.h @@ -0,0 +1,27 @@ + +#ifndef _SPIF_COMPAT_W25XX_H_ +#define _SPIF_COMPAT_W25XX_H_ + +#include "spif_common.h" +#include "spif_internal.h" +#include + + +// W25XX-specific function prototypes +bool SPIF_WriteEnable(SPIF_HandleTypeDef *Handle); +bool SPIF_WriteDisable(SPIF_HandleTypeDef *Handle); +bool SPIF_WaitForWriting(SPIF_HandleTypeDef *Handle, uint32_t Timeout); +uint8_t SPIF_ReadReg1(SPIF_HandleTypeDef *Handle); +uint8_t SPIF_ReadReg2(SPIF_HandleTypeDef *Handle); +uint8_t SPIF_ReadReg3(SPIF_HandleTypeDef *Handle); +bool SPIF_WriteReg1(SPIF_HandleTypeDef *Handle, uint8_t Data); +bool SPIF_WriteReg2(SPIF_HandleTypeDef *Handle, uint8_t Data); +bool SPIF_WriteReg3(SPIF_HandleTypeDef *Handle, uint8_t Data); +bool SPIF_WriteFn(SPIF_HandleTypeDef *Handle, uint32_t PageNumber, uint8_t *Data, uint32_t Size, uint32_t Offset); +bool SPIF_ReadFn(SPIF_HandleTypeDef *Handle, uint32_t Address, uint8_t *Data, uint32_t Size); +bool SPIF_EraseChip(SPIF_HandleTypeDef *Handle); +bool SPIF_EraseSector(SPIF_HandleTypeDef *Handle, uint32_t Sector); +bool SPIF_EraseBlock(SPIF_HandleTypeDef *Handle, uint32_t Block); +bool SPIF_FindChip(SPIF_HandleTypeDef *Handle); + +#endif diff --git a/spif_interface_octospi.c b/spif_interface_octospi.c new file mode 100644 index 0000000..f4aeaf0 --- /dev/null +++ b/spif_interface_octospi.c @@ -0,0 +1,144 @@ +#include "spif_internal.h" +#include "stm32u5xx_hal_ospi.h" +#include "spif.h" + +#if (SPIF_INTERFACE == SPIF_INTERFACE_OCTOSPI) + +bool SPIF_TransmitReceive(SPIF_HandleTypeDef *Handle, uint8_t *Tx, uint8_t *Rx, + size_t Size, uint32_t Timeout) { + + bool retVal = false; + + OSPI_RegularCmdTypeDef sCommand = { 0 }; + OSPI_HandleTypeDef *hospi = (OSPI_HandleTypeDef*) Handle->interface; + SPIF_EmulatedPhases *pc = &Handle->phase_config; + + sCommand.InstructionMode = + pc->instructionEnabled ? + HAL_OSPI_INSTRUCTION_4_LINES : HAL_OSPI_INSTRUCTION_NONE; + sCommand.InstructionSize = + pc->instructionSize == 2 ? + HAL_OSPI_INSTRUCTION_16_BITS : HAL_OSPI_INSTRUCTION_8_BITS; + sCommand.Instruction = pc->instruction; + + sCommand.AddressMode = + pc->addressEnabled ? + HAL_OSPI_ADDRESS_4_LINES : HAL_OSPI_ADDRESS_NONE; + sCommand.AddressSize = + pc->addressSize == 4 ? + HAL_OSPI_ADDRESS_32_BITS : HAL_OSPI_ADDRESS_24_BITS; + sCommand.Address = pc->addressEnabled ? pc->address : 0; + + sCommand.DummyCycles = pc->dummyCycles; + + // Data configuration + sCommand.DataMode = + pc->dataEnabled ? HAL_OSPI_DATA_4_LINES : HAL_OSPI_DATA_NONE; + sCommand.NbData = pc->dataEnabled ? Size : 0; + +// Prepare the command (this could be any relevant command, like a read or write) + if (HAL_OSPI_Command(hospi, &sCommand, Timeout) != HAL_OK) { + dprintf("SPIF COMMAND ERROR\r\n"); + return false; + } + if (HAL_OSPI_TransmitReceive(hospi, Tx, Rx, Size, Timeout) + == HAL_OK) { + retVal = true; + } else { + dprintf("SPIF TIMEOUT\r\n"); + } + + return retVal; +} + +bool SPIF_Transmit(SPIF_HandleTypeDef *Handle, uint8_t *Tx, size_t Size, + uint32_t Timeout) { + + bool retVal = false; + OSPI_RegularCmdTypeDef sCommand = { 0 }; + OSPI_HandleTypeDef *hospi = (OSPI_HandleTypeDef*) Handle->interface; + SPIF_EmulatedPhases *pc = &Handle->phase_config; + + sCommand.InstructionMode = + pc->instructionEnabled ? + HAL_OSPI_INSTRUCTION_4_LINES : HAL_OSPI_INSTRUCTION_NONE; + sCommand.InstructionSize = + pc->instructionSize == 2 ? + HAL_OSPI_INSTRUCTION_16_BITS : HAL_OSPI_INSTRUCTION_8_BITS; + sCommand.Instruction = pc->instruction; + + sCommand.AddressMode = + pc->addressEnabled ? + HAL_OSPI_ADDRESS_4_LINES : HAL_OSPI_ADDRESS_NONE; + sCommand.AddressSize = + pc->addressSize == 4 ? + HAL_OSPI_ADDRESS_32_BITS : HAL_OSPI_ADDRESS_24_BITS; + sCommand.Address = pc->addressEnabled ? pc->address : 0; + + sCommand.DummyCycles = pc->dummyCycles; + + // Data configuration + sCommand.DataMode = + pc->dataEnabled ? HAL_OSPI_DATA_4_LINES : HAL_OSPI_DATA_NONE; + sCommand.NbData = pc->dataEnabled ? Size : 0; + +// Send the command to prepare for the transmission + if (HAL_OSPI_Command(hospi, &sCommand, Timeout) != HAL_OK) { + dprintf("SPIF COMMAND ERROR\r\n"); + return false; + } + + if (HAL_OSPI_Transmit(hospi, Tx, Timeout) == HAL_OK) { + retVal = true; + } else { + dprintf("SPIF TIMEOUT\r\n"); + } + return retVal; + +} + +bool SPIF_Receive(SPIF_HandleTypeDef *Handle, uint8_t *Rx, size_t Size, + uint32_t Timeout) { + + bool retVal = false; + OSPI_RegularCmdTypeDef sCommand = { 0 }; + OSPI_HandleTypeDef *hospi = (OSPI_HandleTypeDef*) Handle->interface; + SPIF_EmulatedPhases *pc = &Handle->phase_config; + + sCommand.InstructionMode = + pc->instructionEnabled ? + HAL_OSPI_INSTRUCTION_4_LINES : HAL_OSPI_INSTRUCTION_NONE; + sCommand.InstructionSize = + pc->instructionSize == 2 ? + HAL_OSPI_INSTRUCTION_16_BITS : HAL_OSPI_INSTRUCTION_8_BITS; + sCommand.Instruction = pc->instruction; + + sCommand.AddressMode = + pc->addressEnabled ? + HAL_OSPI_ADDRESS_4_LINES : HAL_OSPI_ADDRESS_NONE; + sCommand.AddressSize = + pc->addressSize == 4 ? + HAL_OSPI_ADDRESS_32_BITS : HAL_OSPI_ADDRESS_24_BITS; + sCommand.Address = pc->addressEnabled ? pc->address : 0; + + sCommand.DummyCycles = pc->dummyCycles; + + // Data configuration + sCommand.DataMode = + pc->dataEnabled ? HAL_OSPI_DATA_4_LINES : HAL_OSPI_DATA_NONE; + sCommand.NbData = pc->dataEnabled ? Size : 0; + if (HAL_OSPI_Command(hospi, &sCommand, Timeout) != HAL_OK) { + dprintf("SPIF COMMAND ERROR\r\n"); + return false; + } + + if (HAL_OSPI_Receive(hospi, Rx, Timeout) == HAL_OK) { + retVal = true; + } else { + dprintf("SPIF TIMEOUT\r\n"); + } + return retVal; + +} + +#endif diff --git a/spif_interface_spi.c b/spif_interface_spi.c new file mode 100644 index 0000000..58c169d --- /dev/null +++ b/spif_interface_spi.c @@ -0,0 +1,249 @@ +#include "spif_internal.h" +#include "spif.h" + +#if(SPIF_INTERFACE == SPIF_INTERFACE_SPI) + + +bool SPI_SendInstruction(SPIF_HandleTypeDef *Handle, uint32_t Timeout); +bool SPI_SendAddress(SPIF_HandleTypeDef *Handle, uint32_t Timeout); +bool SPI_SendDummyCycles(SPIF_HandleTypeDef *Handle, uint32_t Timeout); + + +// Instruction Phase +bool SPI_SendInstruction(SPIF_HandleTypeDef *Handle, uint32_t Timeout) { + bool retVal = false; + SPIF_EmulatedPhases *pc = &Handle->phase_config; + + SPI_HandleTypeDef *hspi = (SPI_HandleTypeDef*) Handle->interface; + retVal = HAL_SPI_Transmit(hspi, &pc->instruction, pc->instructionSize, + Timeout) == HAL_OK; + + return retVal; + +} + +// Address Phase +bool SPI_SendAddress(SPIF_HandleTypeDef *Handle, uint32_t Timeout) { + bool retVal = false; + SPIF_EmulatedPhases *pc = &Handle->phase_config; + uint32_t Address = pc->address; + SPI_HandleTypeDef *hspi = (SPI_HandleTypeDef*) Handle->interface; + uint8_t addrBytes[4] = { 0 }; + for (int i = 0; i < pc->addressSize; i++) { + addrBytes[i] = (Address >> (8 * i)) & 0xFF; + } + retVal = HAL_SPI_Transmit(hspi, addrBytes, pc->addressSize, Timeout) + == HAL_OK; + return retVal; +} + +// Dummy Cycles Phase +bool SPI_SendDummyCycles(SPIF_HandleTypeDef *Handle, uint32_t Timeout) { + SPIF_EmulatedPhases *pc = &Handle->phase_config; + if (pc->dummyCycles > 0) { + SPI_HandleTypeDef *hspi = (SPI_HandleTypeDef*) Handle->interface; + uint8_t dummy = 0x00; + for (int i = 0; i < pc->dummyCycles; i++) { + if (HAL_SPI_Transmit(hspi, &dummy, 1, Timeout) != HAL_OK) { + return false; + } + } + } + return true; +} + + +bool SPIF_TransmitReceive(SPIF_HandleTypeDef *Handle, uint8_t *Tx, uint8_t *Rx, + size_t Size, uint32_t Timeout) { + bool retVal = false; + +#if (SPIF_PLATFORM == SPIF_PLATFORM_HAL) + SPI_HandleTypeDef *hspi = (SPI_HandleTypeDef*) Handle->interface; + SPIF_EmulatedPhases *pc = &Handle->phase_config; + + if (pc->instructionEnabled) { + retVal = SPI_SendInstruction(Handle, Timeout); + if (!retVal) { + return retVal; + } + } + + if (pc->addressEnabled) { + retVal = SPI_SendAddress(Handle, Timeout); + if (!retVal) { + return retVal; + } + } + + if (pc->dummyCycles > 0) { + retVal = SPI_SendDummyCycles(Handle, Timeout); + if (!retVal) { + return retVal; + } + } + + if (pc->dataEnabled) { + if (HAL_SPI_TransmitReceive(hspi, Tx, Rx, Size, Timeout) + == HAL_OK) { + retVal = true; + } else { + dprintf("SPIF TIMEOUT\r\n"); + } + } +#elif (SPIF_PLATFORM == SPIF_PLATFORM_HAL_DMA) + uint32_t startTime = HAL_GetTick(); + if (HAL_SPI_TransmitReceive_DMA(Handle->interface, Tx, Rx, Size) != HAL_OK) + { + dprintf("SPIF TRANSFER ERROR\r\n"); + } + else + { + while (1) + { + SPIF_Delay(1); + if (HAL_GetTick() - startTime >= Timeout) + { + dprintf("SPIF TIMEOUT\r\n"); + HAL_SPI_DMAStop(Handle->interface); + break; + } + if (HAL_SPI_GetState(Handle->interface) == HAL_SPI_STATE_READY) + { + retVal = true; + break; + } + } + } +#endif + return retVal; +} + +bool SPIF_Transmit(SPIF_HandleTypeDef *Handle, uint8_t *Tx, size_t Size, + uint32_t Timeout) { + + bool retVal = false; + +#if (SPIF_PLATFORM == SPIF_PLATFORM_HAL) + + SPI_HandleTypeDef *hspi = (SPI_HandleTypeDef*) Handle->interface; + SPIF_EmulatedPhases *pc = &Handle->phase_config; + + if (pc->instructionEnabled) { + retVal = SPI_SendInstruction(Handle, Timeout); + if (!retVal) { + return retVal; + } + } + + if (pc->addressEnabled) { + retVal = SPI_SendAddress(Handle, Timeout); + if (!retVal) { + return retVal; + } + } + + if (pc->dummyCycles > 0) { + retVal = SPI_SendDummyCycles(Handle, Timeout); + if (!retVal) { + return retVal; + } + } + + if (pc->dataEnabled) { + if (HAL_SPI_Transmit(hspi, Tx, Size, Timeout) == HAL_OK) { + retVal = true; + } else { + dprintf("SPIF TIMEOUT\r\n"); + } + } +#elif (SPIF_PLATFORM == SPIF_PLATFORM_HAL_DMA) + uint32_t startTime = HAL_GetTick(); + if (HAL_SPI_Transmit_DMA(Handle->interface, Tx, Size) != HAL_OK) + { + dprintf("SPIF TRANSFER ERROR\r\n"); + } + else + { + while (1) + { + SPIF_Delay(1); + if (HAL_GetTick() - startTime >= Timeout) + { + dprintf("SPIF TIMEOUT\r\n"); + HAL_SPI_DMAStop(Handle->interface); + break; + } + if (HAL_SPI_GetState(Handle->interface) == HAL_SPI_STATE_READY) + { + retVal = true; + break; + } + } + } +#endif + return retVal; +} + +bool SPIF_Receive(SPIF_HandleTypeDef *Handle, uint8_t *Rx, size_t Size, + uint32_t Timeout) { + + bool retVal = false; +#if (SPIF_PLATFORM == SPIF_PLATFORM_HAL) + SPI_HandleTypeDef *hspi = (SPI_HandleTypeDef*) Handle->interface; + SPIF_EmulatedPhases *pc = &Handle->phase_config; + + if (pc->instructionEnabled) { + retVal = SPI_SendInstruction(Handle, Timeout); + if (!retVal) { + return retVal; + } + } + + if (pc->addressEnabled) { + retVal = SPI_SendAddress(Handle, Timeout); + if (!retVal) { + return retVal; + } + } + + if (pc->dummyCycles > 0) { + retVal = SPI_SendDummyCycles(Handle, Timeout); + if (!retVal) { + return retVal; + } + } + + if (HAL_SPI_Receive(hspi, Rx, Size, Timeout) == HAL_OK) { + retVal = true; + } else { + dprintf("SPIF TIMEOUT\r\n"); + } +#elif (SPIF_PLATFORM == SPIF_PLATFORM_HAL_DMA) + uint32_t startTime = HAL_GetTick(); + if (HAL_SPI_Receive_DMA(Handle->interface, Rx, Size) != HAL_OK) + { + dprintf("SPIF TRANSFER ERROR\r\n"); + } + else + { + while (1) + { + SPIF_Delay(1); + if (HAL_GetTick() - startTime >= Timeout) + { + dprintf("SPIF TIMEOUT\r\n"); + HAL_SPI_DMAStop(Handle->interface); + break; + } + if (HAL_SPI_GetState(Handle->interface) == HAL_SPI_STATE_READY) + { + retVal = true; + break; + } + } + } +#endif + return retVal; +} + +#endif diff --git a/spif_internal.c b/spif_internal.c new file mode 100644 index 0000000..43b5005 --- /dev/null +++ b/spif_internal.c @@ -0,0 +1,114 @@ +/* + * spif_util.c + * + * Created on: May 15, 2025 + * Author: Megh Shah + */ + +#include "spif_internal.h" + +/***********************************************************************************************************/ + +void SPIF_Delay(uint32_t Delay) +{ +#if SPIF_RTOS == SPIF_RTOS_DISABLE + HAL_Delay(Delay); +#elif (SPIF_RTOS == SPIF_RTOS_CMSIS_V1) || (SPIF_RTOS == SPIF_RTOS_CMSIS_V2) + uint32_t d = (configTICK_RATE_HZ * Delay) / 1000; + if (d == 0) + d = 1; + osDelay(d); +#elif SPIF_RTOS == SPIF_RTOS_THREADX + uint32_t d = (TX_TIMER_TICKS_PER_SECOND * Delay) / 1000; + if (d == 0) + d = 1; + tx_thread_sleep(d); +#endif +} + +/***********************************************************************************************************/ + +void SPIF_Lock(SPIF_HandleTypeDef *Handle) +{ + while (Handle->Lock) + { + SPIF_Delay(1); + } + Handle->Lock = 1; +} + +/***********************************************************************************************************/ + +void SPIF_UnLock(SPIF_HandleTypeDef *Handle) +{ + Handle->Lock = 0; +} + +/***********************************************************************************************************/ + +void SPIF_CsPin(SPIF_HandleTypeDef *Handle, bool Select) +{ + HAL_GPIO_WritePin(Handle->Gpio, Handle->Pin, (GPIO_PinState)Select); + for (int i = 0; i < 10; i++); +} + +/***********************************************************************************************************/ +/* +* @brief Sets the instruction phase parameters +* +* @param phases Pointer to the SPIF_EmulatedPhases structure +* @param enabled Whether the instruction phase is enabled +* @param size Size of the instruction in bytes +* @param instruction The instruction value +*/ +void SPIF_SetCommandPhase(SPIF_HandleTypeDef* handle, bool enabled, uint8_t size, uint8_t instruction) { + + handle->phase_config.instructionEnabled= enabled; + handle->phase_config.instructionSize = size; + handle->phase_config.instruction = instruction; + +} + + +/** + * @brief Sets the address phase parameters + * + * @param phases Pointer to the SPIF_EmulatedPhases structure + * @param enabled Whether the address phase is enabled + * @param size Size of the address in bytes (typically 1-4) + * @param address The address value + */ +void SPIF_SetAddressPhase(SPIF_HandleTypeDef *handle, bool enabled, uint8_t size, uint32_t address) { + + + handle->phase_config.addressEnabled = enabled; + handle->phase_config.addressSize = size; + handle->phase_config.address = address; + +} + + +/** + * @brief Sets the dummy cycles parameter + * + * @param phases Pointer to the SPIF_EmulatedPhases structure + * @param cycles Number of dummy cycles + */ +void SPIF_SetDummyCycles(SPIF_HandleTypeDef *handle, uint8_t cycles) { + + handle->phase_config.dummyCycles = cycles; + +} + + +/** + * @brief Sets the data phase parameters + * + * @param phases Pointer to the SPIF_EmulatedPhases structure + * @param enabled Whether the data phase is enabled + * @param length Length of data in bytes + */ +void SPIF_SetDataPhase(SPIF_HandleTypeDef *handle, bool enabled) { + + handle->phase_config.dataEnabled = enabled; +} diff --git a/spif_internal.h b/spif_internal.h new file mode 100644 index 0000000..9e15362 --- /dev/null +++ b/spif_internal.h @@ -0,0 +1,62 @@ +/* + * spif_types.h + * + * Created on: May 15, 2025 + * Author: Megh Shah + */ + +#ifndef INC_SPIF_INTERNAL_H_ +#define INC_SPIF_INTERNAL_H_ + +#include +#include +#include "stm32u5xx_hal.h" + +#include "spif_common.h" + + + +/************************************************************************************************************ + ************** Public Definitions + ************************************************************************************************************/ + +#define SPIF_PAGE_SIZE 0x100 +#define SPIF_SECTOR_SIZE 0x1000 +#define SPIF_BLOCK_SIZE 0x10000 + +#define SPIF_PageToSector(PageNumber) (((PageNumber) * SPIF_PAGE_SIZE) / SPIF_SECTOR_SIZE) +#define SPIF_PageToBlock(PageNumber) (((PageNumber) * SPIF_PAGE_SIZE) / SPIF_BLOCK_SIZE) +#define SPIF_SectorToBlock(SectorNumber) (((SectorNumber) * SPIF_SECTOR_SIZE) / SPIF_BLOCK_SIZE) +#define SPIF_SectorToPage(SectorNumber) (((SectorNumber) * SPIF_SECTOR_SIZE) / SPIF_PAGE_SIZE) +#define SPIF_BlockToPage(BlockNumber) (((BlockNumber) * SPIF_BLOCK_SIZE) / SPIF_PAGE_SIZE) +#define SPIF_PageToAddress(PageNumber) ((PageNumber) * SPIF_PAGE_SIZE) +#define SPIF_SectorToAddress(SectorNumber) ((SectorNumber) * SPIF_SECTOR_SIZE) +#define SPIF_BlockToAddress(BlockNumber) ((BlockNumber) * SPIF_BLOCK_SIZE) +#define SPIF_AddressToPage(Address) ((Address) / SPIF_PAGE_SIZE) +#define SPIF_AddressToSector(Address) ((Address) / SPIF_SECTOR_SIZE) +#define SPIF_AddressToBlock(Address) ((Address) / SPIF_BLOCK_SIZE) + + + + +/*Helper Functions*/ +void SPIF_Delay(uint32_t Delay); +void SPIF_Lock(SPIF_HandleTypeDef *Handle); +void SPIF_UnLock(SPIF_HandleTypeDef *Handle); +void SPIF_CsPin(SPIF_HandleTypeDef *Handle, bool Select); + + +void SPIF_SetInstructionPhase(SPIF_HandleTypeDef* handle, bool enabled, uint8_t size, uint8_t instruction); +void SPIF_SetAddressPhase(SPIF_HandleTypeDef *handle, bool enabled, uint8_t size, uint32_t address); +void SPIF_SetDummyCycles(SPIF_HandleTypeDef *handle, uint8_t cycles); +void SPIF_SetDataPhase(SPIF_HandleTypeDef *handle, bool enabled); + +bool SPIF_TransmitReceive(SPIF_HandleTypeDef *Handle, uint8_t *Tx, + uint8_t *Rx, size_t Size, uint32_t Timeout); +bool SPIF_Transmit(SPIF_HandleTypeDef *Handle, uint8_t *Tx, size_t Size, + uint32_t Timeout); +bool SPIF_Receive(SPIF_HandleTypeDef *Handle, uint8_t *Rx, size_t Size, + uint32_t Timeout); + + +#endif /* INC_SPIF_INTERNAL_H_ */