/** ****************************************************************************** * @file stm32303c_eval_spi_ee.c * @author MCD Application Team * @version V1.0.1 * @date 23-October-2012 * @brief This file provides a set of functions needed to manage the SPI M95xxx * EEPROM memory mounted on STM32303C-EVAL board (refer to stm32303c_eval.h * to know about the boards supporting this memory). * It implements a high level communication layer for read and write * from/to this memory. The needed STM32F30x hardware resources (SPI and * GPIO) are defined in stm32303c_eval.h file, and the initialization is * performed in SPI_sEE_LowLevel_Init() function declared in stm32303c_eval.c * file. * You can easily tailor this driver to any other development board, * by just adapting the defines for hardware resources and * SPI_sEE_LowLevel_Init() function. * * +-----------------------------------------------------------+ * | Pin assignment | * +-----------------------------+---------------+-------------+ * | STM32 SPI Pins | sEE | Pin | * +-----------------------------+---------------+-------------+ * | sEE_CS_PIN | ChipSelect | 1 (/S) | * | sEE_MISO_PIN / MISO | DataOut | 2 (Q) | * | sEE_WP_PIN | WriteProtect | 3 (/W) | * | | GND | 4 (0 V) | * | sEE_MOSI_PIN / MOSI | DataIn | 5 (D) | * | sEE_SCK_PIN / SCLK | Clock | 6 (C) | * | | Hold | 7 (/HOLD)| * | | VCC | 8 (3.3 V)| * +-----------------------------+---------------+-------------+ ****************************************************************************** * @attention * *

© COPYRIGHT 2012 STMicroelectronics

* * Licensed under MCD-ST Liberty SW License Agreement V2, (the "License"); * You may not use this file except in compliance with the License. * You may obtain a copy of the License at: * * http://www.st.com/software_license_agreement_liberty_v2 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * ****************************************************************************** */ /* Includes ------------------------------------------------------------------*/ #include "stm32303c_eval_spi_ee.h" /** @addtogroup Utilities * @{ */ /** @addtogroup STM32_EVAL * @{ */ /** @addtogroup STM32303C_EVAL * @{ */ /** @addtogroup STM32303C_EVAL_SPI_EE * @brief This file includes the M95xxx SPI EEPROM driver of STM32303C-EVAL boards. * @{ */ /** @defgroup STM32303C_EVAL_SPI_EEPROM_Private_Types * @{ */ uint16_t sEE_DataNum; /** * @} */ /** @defgroup STM32303C_EVAL_SPI_EEPROM_Private_Defines * @{ */ /** * @} */ /** @defgroup STM32303C_EVAL_SPI_EEPROM_Private_Macros * @{ */ /** * @} */ /** @defgroup STM32303C_EVAL_SPI_EEPROM_Private_Variables * @{ */ /** * @} */ /** @defgroup STM32303C_EVAL_SPI_EEPROM_Private_Function_Prototypes * @{ */ /** * @} */ /** @defgroup STM32303C_EVAL_SPI_EEPROM_Private_Functions * @{ */ /** * @brief DeInitializes the peripherals used by the SPI EEPROM driver. * @param None * @retval None */ void sEE_DeInit(void) { sEE_SPI_LowLevel_DeInit(); } /** * @brief Initializes the peripherals used by the SPI EEPROM driver. * @param None * @retval None */ void sEE_Init(void) { sEE_SPI_LowLevel_Init(); /*!< Deselect the EEPROM: Chip Select high */ sEE_CS_HIGH(); } /** * @brief Writes more than one byte to the EEPROM with a single WRITE cycle * (Page WRITE sequence). * @note The number of byte can't exceed the EEPROM page size. * @param pBuffer: pointer to the buffer containing the data to be written * to the EEPROM. * @param WriteAddr: EEPROM's internal address to write to. * @param NumByteToWrite: number of bytes to write to the EEPROM, must be equal * or less than "sEE_PAGESIZE" value. * @retval None */ uint32_t sEE_WritePage(uint8_t* pBuffer, uint16_t WriteAddr, uint16_t* NumByteToWrite) { /*!< Enable the write access to the EEPROM */ sEE_WriteEnable(); /*!< Select the EEPROM: Chip Select low */ sEE_CS_LOW(); /*!< Send "Write to Memory " instruction */ sEE_SendByte(sEE_CMD_WRITE); /*!< Send WriteAddr high nibble address byte to write to */ sEE_SendByte((WriteAddr & 0xFF0000) >> 16); /*!< Send WriteAddr medium nibble address byte to write to */ sEE_SendByte((WriteAddr & 0xFF00) >> 8); /*!< Send WriteAddr low nibble address byte to write to */ sEE_SendByte(WriteAddr & 0xFF); /*!< while there is data to be written on the EEPROM */ while ((*NumByteToWrite)--) { /*!< Send the current byte */ sEE_SendByte(*pBuffer); /*!< Point on the next byte to be written */ pBuffer++; } /*!< Deselect the EEPROM: Chip Select high */ sEE_CS_HIGH(); /*!< Wait the end of EEPROM writing */ sEE_WaitEepromStandbyState(); /*!< Disable the write access to the EEROM */ sEE_WriteDisable(); return 0; } /** * @brief Writes block of data to the EEPROM. In this function, the number of * WRITE cycles are reduced, using Page WRITE sequence. * @param pBuffer: pointer to the buffer containing the data to be written * to the EEPROM. * @param WriteAddr: EEPROM's internal address to write to. * @param NumByteToWrite: number of bytes to write to the EEPROM. * @retval None */ void sEE_WriteBuffer(uint8_t* pBuffer, uint16_t WriteAddr, uint16_t NumByteToWrite) { uint16_t NumOfPage = 0, NumOfSingle = 0, Addr = 0, count = 0, temp = 0; Addr = WriteAddr % sEE_PAGESIZE; count = sEE_PAGESIZE - Addr; NumOfPage = NumByteToWrite / sEE_PAGESIZE; NumOfSingle = NumByteToWrite % sEE_PAGESIZE; if (Addr == 0) /*!< WriteAddr is sEE_PAGESIZE aligned */ { if (NumOfPage == 0) /*!< NumByteToWrite < sEE_PAGESIZE */ { sEE_DataNum = NumByteToWrite; sEE_WritePage(pBuffer, WriteAddr, &sEE_DataNum); } else /*!< NumByteToWrite > sEE_PAGESIZE */ { while (NumOfPage--) { sEE_DataNum = sEE_PAGESIZE; sEE_WritePage(pBuffer, WriteAddr, &sEE_DataNum); WriteAddr += sEE_PAGESIZE; pBuffer += sEE_PAGESIZE; } sEE_DataNum = NumOfSingle; sEE_WritePage(pBuffer, WriteAddr, &sEE_DataNum); } } else /*!< WriteAddr is not sEE_PAGESIZE aligned */ { if (NumOfPage == 0) /*!< NumByteToWrite < sEE_PAGESIZE */ { if (NumOfSingle > count) /*!< (NumByteToWrite + WriteAddr) > sEE_PAGESIZE */ { temp = NumOfSingle - count; sEE_DataNum = count; sEE_WritePage(pBuffer, WriteAddr, &sEE_DataNum); WriteAddr += count; pBuffer += count; sEE_DataNum = temp; sEE_WritePage(pBuffer, WriteAddr, &sEE_DataNum); } else { sEE_DataNum = NumByteToWrite; sEE_WritePage(pBuffer, WriteAddr, &sEE_DataNum); } } else /*!< NumByteToWrite > sEE_PAGESIZE */ { NumByteToWrite -= count; NumOfPage = NumByteToWrite / sEE_PAGESIZE; NumOfSingle = NumByteToWrite % sEE_PAGESIZE; sEE_DataNum = count; sEE_WritePage(pBuffer, WriteAddr, &sEE_DataNum); WriteAddr += count; pBuffer += count; while (NumOfPage--) { sEE_DataNum = sEE_PAGESIZE; sEE_WritePage(pBuffer, WriteAddr, &sEE_DataNum); WriteAddr += sEE_PAGESIZE; pBuffer += sEE_PAGESIZE; } if (NumOfSingle != 0) { sEE_DataNum = NumOfSingle; sEE_WritePage(pBuffer, WriteAddr, &sEE_DataNum); } } } } /** * @brief Reads a block of data from the EEPROM. * @param pBuffer: pointer to the buffer that receives the data read from the EEPROM. * @param ReadAddr: EEPROM's internal address to read from. * @param NumByteToRead: number of bytes to read from the EEPROM. * @retval None */ uint32_t sEE_ReadBuffer(uint8_t* pBuffer, uint16_t ReadAddr, uint16_t* NumByteToRead) { /*!< Select the EEPROM: Chip Select low */ sEE_CS_LOW(); /*!< Send "Write to Memory " instruction */ sEE_SendByte(sEE_CMD_READ); /*!< Send WriteAddr high nibble address byte to write to */ sEE_SendByte((ReadAddr & 0xFF0000) >> 16); /*!< Send WriteAddr medium nibble address byte to write to */ sEE_SendByte((ReadAddr & 0xFF00) >> 8); /*!< Send WriteAddr low nibble address byte to write to */ sEE_SendByte(ReadAddr & 0xFF); while ((*NumByteToRead)--) /*!< while there is data to be read */ { /*!< Read a byte from the EEPROM */ *pBuffer = sEE_SendByte(sEE_DUMMY_BYTE); /*!< Point to the next location where the byte read will be saved */ pBuffer++; } /*!< Deselect the EEPROM: Chip Select high */ sEE_CS_HIGH(); return 0; } /** * @brief Reads a byte from the SPI EEPROM. * @note This function must be used only if the Start_Read_Sequence function * has been previously called. * @param None * @retval Byte Read from the SPI EEPROM. */ uint8_t sEE_ReadByte(void) { return (sEE_SendByte(sEE_DUMMY_BYTE)); } /** * @brief Sends a byte through the SPI interface and return the byte received * from the SPI bus. * @param byte: byte to send. * @retval The value of the received byte. */ uint8_t sEE_SendByte(uint8_t byte) { /*!< Loop while DR register in not empty */ while (SPI_I2S_GetFlagStatus(sEE_SPI, SPI_I2S_FLAG_TXE) == RESET); /*!< Send byte through the SPI peripheral */ SPI_SendData8(sEE_SPI, byte); /*!< Wait to receive a byte */ while (SPI_I2S_GetFlagStatus(sEE_SPI, SPI_I2S_FLAG_RXNE) == RESET); /*!< Return the byte read from the SPI bus */ return SPI_ReceiveData8(sEE_SPI); } /** * @brief Enables the write access to the EEPROM. * @param None * @retval None */ void sEE_WriteEnable(void) { /*!< Select the EEPROM: Chip Select low */ sEE_CS_LOW(); /*!< Send "Write Enable" instruction */ sEE_SendByte(sEE_CMD_WREN); /*!< Deselect the EEPROM: Chip Select high */ sEE_CS_HIGH(); } /** * @brief Disables the write access to the EEPROM. * @param None * @retval None */ void sEE_WriteDisable(void) { /*!< Select the EEPROM: Chip Select low */ sEE_CS_LOW(); /*!< Send "Write Disable" instruction */ sEE_SendByte(sEE_CMD_WRDI); /*!< Deselect the EEPROM: Chip Select high */ sEE_CS_HIGH(); } /** * @brief Write new value in EEPROM Status Register. * @param regval : new value of register * @retval None */ void sEE_WriteStatusRegister(uint8_t regval) { /*!< Select the EEPROM: Chip Select low */ sEE_CS_LOW(); /*!< Enable the write access to the EEPROM */ sEE_WriteEnable(); /*!< Send "Write Status Register" instruction */ sEE_SendByte(sEE_CMD_WRSR); /*!< Write regval in status register */ sEE_SendByte(regval); /*!< Deselect the EEPROM: Chip Select high */ sEE_CS_HIGH(); } /** * @brief Read EEPROM Status Register. * @param None * @retval The value of the Status register. */ uint8_t sEE_ReadStatusRegister(void) { uint8_t sEEstatus = 0; /*!< Select the EEPROM: Chip Select low */ sEE_CS_LOW(); /*!< Send "Read Status Register" instruction */ sEE_SendByte(sEE_CMD_RDSR); /*!< Send a dummy byte to generate the clock needed by the EEPROM and put the value of the status register in EEPROM Status variable */ sEEstatus = sEE_SendByte(sEE_DUMMY_BYTE); /*!< Deselect the EEPROM: Chip Select high */ sEE_CS_HIGH(); return sEEstatus; } /** * @brief Polls the status of the Write In Progress (WIP) flag in the EEPROM's * status register and loop until write operation has completed. * @param None * @retval None */ uint32_t sEE_WaitEepromStandbyState(void) { uint8_t sEEstatus = 0; /*!< Select the EEPROM: Chip Select low */ sEE_CS_LOW(); /*!< Send "Read Status Register" instruction */ sEE_SendByte(sEE_CMD_RDSR); /*!< Loop as long as the memory is busy with a write cycle */ do { /*!< Send a dummy byte to generate the clock needed by the EEPROM and put the value of the status register in EEPROM Status variable */ sEEstatus = sEE_SendByte(sEE_DUMMY_BYTE); } while ((sEEstatus & sEE_WIP_FLAG) == SET); /* Write in progress */ /*!< Deselect the EEPROM: Chip Select high */ sEE_CS_HIGH(); return 0; } /** * @} */ /** * @} */ /** * @} */ /** * @} */ /** * @} */ /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/