/** * @brief Reads Block protection. * @param BlockRegData array * @retval None */ #include #include "FlashMemory_SST26VF_driver.h" #include "FlashMemory_SST26VF_user.h" volatile uint8_t Dummy; static void SST26VF_Wait(volatile uint32_t Loop); /*----------------------------------------------------------------------------*/ /** * @fn SST26VF_SPI_WriteByte(uint8_t byteData) * @brief SPIバイト書込み * @param[in] byteData 送信データ * @detail SPI送信 * @note */ /*----------------------------------------------------------------------------*/ void SST26VF_SPI_WriteByte(uint8_t byteData) { while(SPIXTBF == 1U) { ; } SPI1BUF = byteData; } /*----------------------------------------------------------------------------*/ /** * @fn SST26VF_SPI_ExchangeByte(uint8_t byteData) * @brief SPI送受信 * @param[in] byteData 送信データ * @retval 受信データ * @detail SPI送受信 * @note */ /*----------------------------------------------------------------------------*/ uint8_t SST26VF_SPI_ExchangeByte(uint8_t byteData) { while(SPIXTBF == 1u){;} SPI1BUF = byteData; while(SPIXRBE == 1u){;} return (uint8_t) SPI1BUF; } /*----------------------------------------------------------------------------*/ /** * @fn SST26VF_SPI_ReadByte(void) * @brief SPI受信 * @retval 受信データ * @detail SPI受信 * @note */ /*----------------------------------------------------------------------------*/ uint8_t SST26VF_SPI_ReadByte(void) { while(SPIXRBE == 1u){;} return (uint8_t) SPI1BUF; } /*----------------------------------------------------------------------------*/ /** * @fn SST26VF_SPI_Transmit(uint8_t *txData,uint32_t Length) * @brief SPI送信 * @param[in] *txData 送信データポインタ * @param[in] Length 送信データ長 * @detail SPI送信 * @note */ /*----------------------------------------------------------------------------*/ void SST26VF_SPI_Transmit(uint8_t *txData,uint32_t Length) { while ( Length --) { Dummy = SST26VF_SPI_ExchangeByte(*txData++); } } /*----------------------------------------------------------------------------*/ /** * @fn SST26VF_SPI_Receive(uint8_t *rxData,uint32_t Length) * @brief SPI受信 * @param[in] *rxData 受信データポインタ * @param[in] Length 送信データ長 * @detail SPI受信 * @note */ /*----------------------------------------------------------------------------*/ void SST26VF_SPI_Receive(uint8_t *rxData,uint32_t Length) { while ( Length --) { *rxData++ = SST26VF_SPI_ExchangeByte(0); } } /*----------------------------------------------------------------------------*/ /** * @fn SST26VF_SPI_CS(uint8_t cs) * @brief CSピン制御 * @param[in] cs CSピンレベル * @detail CSピン制御 * @note */ /*----------------------------------------------------------------------------*/ void SST26VF_SPI_CS(uint8_t cs) { SPIXCS = cs & 0x01; } /*----------------------------------------------------------------------------*/ /** * @fn void SST26VF_Reset(void) * @brief リセット * @detail リセット * @note */ /*----------------------------------------------------------------------------*/ void SST26VF_Reset(void) { /*------------------------------------------------------------------------*/ /* ローカル変数の定義と初期化 */ /*------------------------------------------------------------------------*/ uint8_t txData[1]; uint32_t Cnt = 2000000; txData[0] = SST26VF_CMD_RSTEN; /*------------------------------------------------------------------------*/ /* コマンド実行 */ /*------------------------------------------------------------------------*/ SST26VF_SPI_CS(0u); SST26VF_SPI_Transmit( txData, sizeof(txData)); SST26VF_SPI_CS(1u); /*------------------------------------------------------------------------*/ /* Wait TCPH */ /*------------------------------------------------------------------------*/ while(Cnt --){;} /*------------------------------------------------------------------------*/ /* ローカル変数の設定 */ /*------------------------------------------------------------------------*/ txData[0] = SST26VF_CMD_RST; /*------------------------------------------------------------------------*/ /* コマンド実行 */ /*------------------------------------------------------------------------*/ SST26VF_SPI_CS(0u); SST26VF_SPI_Transmit( txData, sizeof(txData)); SST26VF_SPI_CS(1u); } /*----------------------------------------------------------------------------*/ /** * @fn SST26VF_Read_Data(uint8_t *rxData,uint32_t ReadAdrs,uint32_t Length) * @brief データの受信 * @param[in] *rxData  受信バッファ * @param[in] ReadAdrs 受信アドレス * @param[in] Length  受信長 * @detail データの受信 * @note */ /*----------------------------------------------------------------------------*/ void SST26VF_Read_Data(uint8_t *rxData,uint32_t ReadAdrs,uint32_t Length) { /*------------------------------------------------------------------------*/ /* ローカル変数の定義と初期化 */ /*------------------------------------------------------------------------*/ uint8_t txData[4]; txData[0] = SST26VF_CMD_READ; txData[1] = (ReadAdrs >> 16) & 0xFF; txData[2] = (ReadAdrs >> 8) & 0xFF ; txData[3] = ReadAdrs & 0xFF; /*------------------------------------------------------------------------*/ /* コマンド実行 */ /*------------------------------------------------------------------------*/ SST26VF_SPI_CS(0u); SST26VF_SPI_Transmit( txData, sizeof(txData)); SST26VF_SPI_Receive( rxData,Length ); SST26VF_SPI_CS(1u); } /*----------------------------------------------------------------------------*/ /** * @fn SST26VF_HiSpeed_Read_Data(uint8_t *rxData,uint32_t ReadAdrs,uint32_t Length) * @brief データのハイスピード受信 * @param[in] *rxData  受信バッファ * @param[in] ReadAdrs 受信アドレス * @param[in] Length  受信長 * @detail データの受ハイスピード受信 * @note */ /*----------------------------------------------------------------------------*/ void SST26VF_HiSpeed_Read_Data(uint8_t *rxData,uint32_t ReadAdrs,uint32_t Length) { /*------------------------------------------------------------------------*/ /* ローカル変数の定義と初期化 */ /*------------------------------------------------------------------------*/ uint8_t txData[5]; txData[0] = SST26VF_CMD_READ; txData[1] = (ReadAdrs >> 16) & 0xFF; txData[2] = (ReadAdrs >> 8) & 0xFF ; txData[3] = ReadAdrs & 0xFF; txData[4] = 0; //Dummy /*------------------------------------------------------------------------*/ /* コマンド実行 */ /*------------------------------------------------------------------------*/ SST26VF_SPI_CS(0u); SST26VF_SPI_Transmit( txData, sizeof(txData)); SST26VF_SPI_Receive( rxData,Length); SST26VF_SPI_CS(1u); } /*----------------------------------------------------------------------------*/ /** * @fn SST26VF_Read_ID(void) * @brief IDの読込 * @retval ID * @detail IDの読込 * @note */ /*----------------------------------------------------------------------------*/ uint32_t SST26VF_Read_ID(void) { /*------------------------------------------------------------------------*/ /* ローカル変数の定義と初期化 */ /*------------------------------------------------------------------------*/ uint8_t txData[1]; uint8_t rxData[3]; txData[0] = SST26VF_CMD_JID; /*------------------------------------------------------------------------*/ /* コマンド実行 */ /*------------------------------------------------------------------------*/ SST26VF_SPI_CS(0u); SST26VF_SPI_Transmit( txData, sizeof(txData)); SST26VF_SPI_Receive( rxData,sizeof(rxData)); SST26VF_SPI_CS(1u); /*------------------------------------------------------------------------*/ /* リターン */ /*------------------------------------------------------------------------*/ return ((((uint32_t)rxData[0]) << 16) + (((uint32_t)rxData[1]) << 8) + ((uint32_t)rxData[2])); } /*----------------------------------------------------------------------------*/ /** * @fn SST26VF_Read_Status(void) * @brief ステータスレジスタの読込 * @retval ステータスレジスタ * @detail ステータスレジスタの読込 * @note */ /*----------------------------------------------------------------------------*/ uint32_t SST26VF_Read_Status(void) { /*------------------------------------------------------------------------*/ /* ローカル変数の定義と初期化 */ /*------------------------------------------------------------------------*/ uint8_t txData[1]; uint8_t rxData[1]; txData[0] = SST26VF_CMD_RDSR; /*------------------------------------------------------------------------*/ /* コマンド実行 */ /*------------------------------------------------------------------------*/ SST26VF_SPI_CS(0u); SST26VF_SPI_Transmit( txData, sizeof(txData)); SST26VF_SPI_Receive( rxData,sizeof(rxData)); SST26VF_SPI_CS(1u); /*------------------------------------------------------------------------*/ /* リターン */ /*------------------------------------------------------------------------*/ return ((uint32_t)rxData[0]); } /*----------------------------------------------------------------------------*/ /** * @fn SST26VF_Read_Config(void) * @brief コンフィグレジスタの読込 * @retval コンフィグレジスタ * @detail コンフィグレジスタの読込 * @note */ /*----------------------------------------------------------------------------*/ uint32_t SST26VF_Read_Config(void) { /*------------------------------------------------------------------------*/ /* ローカル変数の定義と初期化 */ /*------------------------------------------------------------------------*/ uint8_t txData[1]; uint8_t rxData[1]; txData[0] = SST26VF_CMD_RDCR; /*------------------------------------------------------------------------*/ /* コマンド実行 */ /*------------------------------------------------------------------------*/ SST26VF_SPI_CS(0u); SST26VF_SPI_Transmit( txData, sizeof(txData)); SST26VF_SPI_Receive( rxData,sizeof(rxData)); SST26VF_SPI_CS(1u); /*------------------------------------------------------------------------*/ /* リターン */ /*------------------------------------------------------------------------*/ return ((uint32_t)rxData[0]); } /*----------------------------------------------------------------------------*/ /** * @fn SST26VF_Write_Enable(void) * @brief 書込み有効化 * @detail 書込み有効化 * @note */ /*----------------------------------------------------------------------------*/ void SST26VF_Write_Enable(void) { /*------------------------------------------------------------------------*/ /* ローカル変数の定義と初期化 */ /*------------------------------------------------------------------------*/ uint8_t txData[1]; txData[0] = SST26VF_CMD_WREN; /*------------------------------------------------------------------------*/ /* コマンド実行 */ /*------------------------------------------------------------------------*/ SST26VF_SPI_CS(0u); SST26VF_SPI_Transmit( txData, sizeof(txData)); SST26VF_SPI_CS(1u); } /*----------------------------------------------------------------------------*/ /** * @fn SST26VF_Write_StatusAndConfig(uint8_t Status,uint8_t Config) * @brief ステータスとコンフィグレジスタへの書込み * @param[in] Status ステータスレジスタの値 * @param[in] Config コンフィグレジスタの値 * @detail ステータスとコンフィグレジスタへの書込み * @note */ /*----------------------------------------------------------------------------*/ void SST26VF_Write_StatusAndConfig(uint8_t Status,uint8_t Config) { /*------------------------------------------------------------------------*/ /* ローカル変数の定義と初期化 */ /*------------------------------------------------------------------------*/ uint8_t txData[3]; txData[0] = SST26VF_CMD_WRSR; txData[1] = Status; txData[2] = Config; /*------------------------------------------------------------------------*/ /* コマンド実行 */ /*------------------------------------------------------------------------*/ SST26VF_Write_Enable(); SST26VF_Wait(15); SST26VF_SPI_CS(0u); SST26VF_SPI_Transmit( txData, sizeof(txData)); SST26VF_SPI_CS(1u); } /*----------------------------------------------------------------------------*/ /** * @fn SST26VF_Write_Page(uint8_t *txBuf,uint32_t WriteAdrs,uint32_t Length) * @brief ページライト * @param[in] *txData  書込みバッファ * @param[in] WriteAdrs 書込みアドレス * @param[in] Length  書込み長 * @detail ページライト * @note */ /*----------------------------------------------------------------------------*/ void SST26VF_Write_Page(uint8_t *txBuf,uint32_t WriteAdrs,uint32_t Length) { /*------------------------------------------------------------------------*/ /* ローカル変数の定義と初期化 */ /*------------------------------------------------------------------------*/ uint8_t txData[4]; txData[0] = SST26VF_CMD_PP; txData[1] = (WriteAdrs >> 16) & 0xFF; txData[2] = (WriteAdrs >> 8) & 0xFF ; txData[3] = WriteAdrs & 0xFF; /*------------------------------------------------------------------------*/ /* コマンド実行 */ /*------------------------------------------------------------------------*/ SST26VF_Write_Enable(); SST26VF_Wait(20); SST26VF_SPI_CS(0u); SST26VF_SPI_Transmit( txData, sizeof(txData)); SST26VF_SPI_Transmit( txBuf, Length); SST26VF_SPI_CS(1u); SST26VF_Wait(100); SST26VF_Wait_WriteDone(); } /*----------------------------------------------------------------------------*/ /** * @fn SST26VF_Wait_WriteDone(void) * @brief 書込み完了待ち * @detail 書込み完了待ち * @note */ /*----------------------------------------------------------------------------*/ void SST26VF_Wait_WriteDone(void) { /*------------------------------------------------------------------------*/ /* ローカル変数の定義と初期化 */ /*------------------------------------------------------------------------*/ uint8_t txData[1]; uint8_t rxData[1]; txData[0] = SST26VF_CMD_RDSR; rxData[0] = 0x01u; /*------------------------------------------------------------------------*/ /* コマンド実行 */ /*------------------------------------------------------------------------*/ while ((rxData[0] & 0x01) == 0x01) { SST26VF_SPI_CS(0u); SST26VF_SPI_Transmit( txData, sizeof(txData)); SST26VF_SPI_Receive( rxData,sizeof(rxData)); SST26VF_SPI_CS(1u); SST26VF_Wait(10); } } /*----------------------------------------------------------------------------*/ /** * @fn SST26VF_Erase_Sector(uint32_t SectorAdrs) * @brief セクターの消去 * @param[in] SectorAdrs セクターアドレス * @detail セクターの消去 * @note */ /*----------------------------------------------------------------------------*/ uint32_t SST26VF_Erase_Sector(uint32_t SectorAdrs) { /*------------------------------------------------------------------------*/ /* ローカル変数の定義と初期化 */ /*------------------------------------------------------------------------*/ uint8_t txData[4]; txData[0] = SST26VF_CMD_SE; txData[1] = (SectorAdrs >> 16) & 0xFF; txData[2] = (SectorAdrs >> 8) & 0xFF ; txData[3] = SectorAdrs & 0xFF; /*------------------------------------------------------------------------*/ /* コマンド実行 */ /*------------------------------------------------------------------------*/ SST26VF_Write_Enable(); SST26VF_Wait(30); SST26VF_SPI_CS(0u); SST26VF_SPI_Transmit( txData, sizeof(txData)); SST26VF_SPI_CS(1u); SST26VF_Wait(100); SST26VF_Wait_WriteDone(); } /*----------------------------------------------------------------------------*/ /** * @fn SST26VF_Erase_32KByte_Block(uint32_t BlockAdrs) * @brief 32kBブロック消去 * @param[in] BlockAdrs ブロックアドレス * @detail 32kBブロック消去 * @note */ /*----------------------------------------------------------------------------*/ uint32_t SST26VF_Erase_32KByte_Block(uint32_t BlockAdrs) { /*------------------------------------------------------------------------*/ /* ローカル変数の定義と初期化 */ /*------------------------------------------------------------------------*/ uint8_t txData[4]; txData[0] = SST26VF_CMD_BE32K; txData[1] = (BlockAdrs >> 16) & 0xFF; txData[2] = (BlockAdrs >> 8) & 0xFF ; txData[3] = BlockAdrs & 0xFF; /*------------------------------------------------------------------------*/ /* コマンド実行 */ /*------------------------------------------------------------------------*/ SST26VF_Write_Enable(); SST26VF_Wait(30); SST26VF_SPI_CS(0u); SST26VF_SPI_Transmit( txData, sizeof(txData)); SST26VF_SPI_CS(1u); SST26VF_Wait(100); SST26VF_Wait_WriteDone(); } /*----------------------------------------------------------------------------*/ /** * @fn SST26VF_Erase_64KByte_Block(uint32_t BlockAdrs) * @brief 64kBブロック消去 * @param[in] BlockAdrs ブロックアドレス * @detail 64kBブロック消去 * @note */ /*----------------------------------------------------------------------------*/ uint32_t SST26VF_Erase_64KByte_Block(uint32_t BlockAdrs) { /*------------------------------------------------------------------------*/ /* ローカル変数の定義と初期化 */ /*------------------------------------------------------------------------*/ uint8_t txData[4]; txData[0] = SST26VF_CMD_BE64K; txData[1] = (BlockAdrs >> 16) & 0xFF; txData[2] = (BlockAdrs >> 8) & 0xFF ; txData[3] = BlockAdrs & 0xFF; /*------------------------------------------------------------------------*/ /* コマンド実行 */ /*------------------------------------------------------------------------*/ SST26VF_Write_Enable(); SST26VF_Wait(30); SST26VF_SPI_CS(0u); SST26VF_SPI_Transmit( txData, sizeof(txData)); SST26VF_SPI_CS(1u); SST26VF_Wait(100); SST26VF_Wait_WriteDone(); } /*----------------------------------------------------------------------------*/ /** * @fn SST26VF_Erase_Chip(void) * @brief イレースチップ * @detail イレースチップ * @note */ /*----------------------------------------------------------------------------*/ uint32_t SST26VF_Erase_Chip(void) { /*------------------------------------------------------------------------*/ /* ローカル変数の定義と初期化 */ /*------------------------------------------------------------------------*/ uint8_t txData[1]; txData[0] = SST26VF_CMD_CE; /*------------------------------------------------------------------------*/ /* コマンド実行 */ /*------------------------------------------------------------------------*/ SST26VF_Write_Enable(); SST26VF_Wait(30); SST26VF_SPI_CS(0u); SST26VF_SPI_Transmit( txData, sizeof(txData)); SST26VF_SPI_CS(1u); SST26VF_Wait(100); SST26VF_Wait_WriteDone(); } static void SST26VF_Wait(volatile uint32_t Loop) { while (Loop > 0) { Loop --; } }