/* USER CODE BEGIN Header */ /** ****************************************************************************** * @file user_diskio.c * @brief This file includes a diskio driver skeleton to be completed by the user. ****************************************************************************** * @attention * * Copyright (c) 2025 STMicroelectronics. * All rights reserved. * * This software is licensed under terms that can be found in the LICENSE file * in the root directory of this software component. * If no LICENSE file comes with this software, it is provided AS-IS. * ****************************************************************************** */ /* USER CODE END Header */ #ifdef USE_OBSOLETE_USER_CODE_SECTION_0 /* * Warning: the user section 0 is no more in use (starting from CubeMx version 4.16.0) * To be suppressed in the future. * Kept to ensure backward compatibility with previous CubeMx versions when * migrating projects. * User code previously added there should be copied in the new user sections before * the section contents can be deleted. */ /* USER CODE BEGIN 0 */ /* USER CODE END 0 */ #endif /* USER CODE BEGIN DECL */ /* Includes ------------------------------------------------------------------*/ #include #include #include "ff_gen_drv.h" #include "eeprom_diskio.h" #include "eeprom_conf.h" #include "m24256e.h" /* Private typedef -----------------------------------------------------------*/ /* Private define ------------------------------------------------------------*/ /* Private variables ---------------------------------------------------------*/ /* Disk status */ static volatile DSTATUS Stat = STA_NOINIT; uint8_t M24256E_CDA_DevSelCode = 0xB0; uint8_t M24256E_IDPage_DevSelCode = 0xB0; uint8_t M24256E_Memory_DevSelCode = 0xA0; static M24256E_EEPROM_CommonDrv_t *M24256EDrv[EEICA1_M24_INSTANCES_NBR]; void *M24256ECompObj[EEICA1_M24_INSTANCES_NBR]; /* USER CODE END DECL */ static int32_t M24256E_Probe(void); int32_t M24256E_IsDeviceReady(uint32_t Instance, const uint32_t Trials); int32_t M24256E_ReadPage(uint32_t Instance, uint8_t * const pData, const uint32_t TarAddr, const uint16_t Size); /* Private function prototypes -----------------------------------------------*/ DSTATUS EEPROM_initialize (BYTE pdrv); DSTATUS EEPROM_status (BYTE pdrv); DRESULT EEPROM_read (BYTE pdrv, BYTE *buff, DWORD sector, UINT count); #if _USE_WRITE == 1 DRESULT EEPROM_write (BYTE pdrv, const BYTE *buff, DWORD sector, UINT count); #endif /* _USE_WRITE == 1 */ #if _USE_IOCTL == 1 DRESULT EEPROM_ioctl (BYTE pdrv, BYTE cmd, void *buff); #endif /* _USE_IOCTL == 1 */ Diskio_drvTypeDef EEPROM_Driver = { EEPROM_initialize, EEPROM_status, EEPROM_read, #if _USE_WRITE EEPROM_write, #endif /* _USE_WRITE == 1 */ #if _USE_IOCTL == 1 EEPROM_ioctl, #endif /* _USE_IOCTL == 1 */ }; /* Private functions ---------------------------------------------------------*/ /** * @brief Initializes a Drive * @param pdrv: Physical drive number (0..) * @retval DSTATUS: Operation status */ DSTATUS EEPROM_initialize (BYTE pdrv /* Physical drive nmuber to identify the drive */ ) { /* USER CODE BEGIN INIT */ UNUSED(pdrv); // We have only one EEPROM on the bus Stat = STA_NOINIT; if (M24256E_Probe() == BSP_ERROR_NONE) Stat = 0; return Stat; /* USER CODE END INIT */ } /** * @brief Gets Disk Status * @param pdrv: Physical drive number (0..) * @retval DSTATUS: Operation status */ DSTATUS EEPROM_status ( BYTE pdrv /* Physical drive number to identify the drive */ ) { /* USER CODE BEGIN STATUS */ UNUSED(pdrv); // We have only one EEPROM on the bus Stat = STA_NOINIT; if (M24256E_IsDeviceReady(EEICA1_M24256E, MAX_TRIALS) == BSP_ERROR_NONE) Stat = 0; return Stat; /* USER CODE END STATUS */ } /** * @brief Reads Sector(s) * @param pdrv: Physical drive number (0..) * @param *buff: Data buffer to store read data * @param sector: Sector address (LBA) * @param count: Number of sectors to read (1..128) * @retval DRESULT: Operation result */ DRESULT EEPROM_read ( BYTE pdrv, /* Physical drive nmuber to identify the drive */ BYTE *buff, /* Data buffer to store read data */ DWORD sector, /* Sector address in LBA */ UINT count /* Number of sectors to read */ ) { /* USER CODE BEGIN READ */ UNUSED(pdrv); printf("Requested %u sectors starting at %lu.\n", count, sector); if (M24256E_ReadPage(EEICA1_M24256E, buff, sector * _MIN_SS, count * _MIN_SS) != BSP_ERROR_NONE) return RES_ERROR; return RES_OK; /* USER CODE END READ */ } /** * @brief Writes Sector(s) * @param pdrv: Physical drive number (0..) * @param *buff: Data to be written * @param sector: Sector address (LBA) * @param count: Number of sectors to write (1..128) * @retval DRESULT: Operation result */ #if _USE_WRITE == 1 DRESULT EEPROM_write ( BYTE pdrv, /* Physical drive nmuber to identify the drive */ const BYTE *buff, /* Data to be written */ DWORD sector, /* Sector address in LBA */ UINT count /* Number of sectors to write */ ) { /* USER CODE BEGIN WRITE */ /* USER CODE HERE */ return RES_OK; /* USER CODE END WRITE */ } #endif /* _USE_WRITE == 1 */ /** * @brief I/O control operation * @param pdrv: Physical drive number (0..) * @param cmd: Control code * @param *buff: Buffer to send/receive control data * @retval DRESULT: Operation result */ #if _USE_IOCTL == 1 DRESULT EEPROM_ioctl ( BYTE pdrv, /* Physical drive nmuber (0..) */ BYTE cmd, /* Control code */ void *buff /* Buffer to send/receive control data */ ) { /* USER CODE BEGIN IOCTL */ UNUSED(pdrv); DRESULT res = RES_ERROR; if (Stat & STA_NOINIT) return RES_NOTRDY; switch (cmd) { case CTRL_SYNC: // Make sure that no pending write process res = RES_OK; break; case GET_SECTOR_COUNT: // Get number of sectors on the disk (DWORD) *(DWORD*)buff = M24256E_MEMORYSIZE / _MIN_SS; res = RES_OK; break; case GET_SECTOR_SIZE: // Get R/W sector size (WORD) *(WORD*)buff = _MIN_SS; res = RES_OK; break; case GET_BLOCK_SIZE: // Get erase block size in unit of sector (DWORD) *(DWORD*)buff = 1; res = RES_OK; break; default: res = RES_PARERR; } return res; /* USER CODE END IOCTL */ } #endif /* _USE_IOCTL == 1 */ //------------------------------------------------------------------------------ /** * @brief Reads complete page from the memory at page start address * @param Instance : I2C EEPROM instance to be used * @param pData : pointer to the data to read * @param TarAddr : starting page address to read * @param Size : Size in bytes of the value to be written * @retval BSP status */ int32_t M24256E_ReadPage(uint32_t Instance, uint8_t * const pData, const uint32_t TarAddr, const uint16_t Size) { int32_t ret = BSP_ERROR_NONE; if ((TarAddr + Size)> M24256E_MEMORYSIZE) return BSP_ERROR_WRONG_PARAM; uint32_t iNumberOfPage = (TarAddr + Size) / M24256E_PAGESIZE; uint32_t iRemainder = (TarAddr + Size) % M24256E_PAGESIZE; uint32_t PageAddress = TarAddr * M24256E_PAGESIZE; uint32_t iPageNumber = TarAddr; if (iRemainder != 0U) { iNumberOfPage += 1U; } if (iNumberOfPage <= 1U) { if (M24256EDrv[Instance]->ReadPage(M24256ECompObj[Instance], pData, PageAddress, M24256E_PAGESIZE) != BSP_ERROR_NONE) { ret = BSP_ERROR_COMPONENT_FAILURE; } else { ret = BSP_ERROR_NONE; } } else { for (uint32_t iCounter=0; iCounterReadPage(M24256ECompObj[Instance], &pData[0U + (iCounter*M24256E_PAGESIZE)], iPageAddress, M24256E_PAGESIZE); iPageNumber++; HAL_Delay(5); } } return ret; } //------------------------------------------------------------------------------ /** * @brief Checks if the memory is available * @param Instance : I2C EEPROM instance to be used * @param Trials : Number of trials * @retval BSP status */ int32_t M24256E_IsDeviceReady(uint32_t Instance, const uint32_t Trials) { int32_t ret; if (M24256EDrv[Instance]->IsReady(M24256ECompObj[Instance], Trials) != BSP_ERROR_NONE) { ret = BSP_ERROR_COMPONENT_FAILURE; } else { ret = BSP_ERROR_NONE; } return ret; } //------------------------------------------------------------------------------ /** * @brief Register Bus IOs for instance M24256E * @retval BSP status */ static int32_t M24256E_Probe(void) { M24256E_IO_t io_ctx256; int32_t ret = BSP_ERROR_NONE; static M24256E_Object_t M24256_obj_0; io_ctx256.Address = M24256E_CDA_DevSelCode; io_ctx256.Init = EEICA1_I2C_INIT; io_ctx256.DeInit = EEICA1_I2C_DEINIT; io_ctx256.ReadReg = EEICA1_I2C_READREG; io_ctx256.WriteReg = EEICA1_I2C_WRITEREG; io_ctx256.ReadReg16 = EEICA1_I2C_READREG16; io_ctx256.WriteReg16 = EEICA1_I2C_WRITEREG16; io_ctx256.Transmit = EEICA1_I2C_SEND; io_ctx256.IsReady = EEICA1_I2C_ISREADY; io_ctx256.Delay = EEICA1_M24_DELAY; if (M24256E_RegisterBusIO(&M24256_obj_0, &io_ctx256) != M24_OK) { ret = BSP_ERROR_UNKNOWN_COMPONENT; } M24256ECompObj[EEICA1_M24256E] = &M24256_obj_0; M24256EDrv[EEICA1_M24256E] = (M24256E_EEPROM_CommonDrv_t *)(void *)&M24256E_i2c_Drv; if (M24256EDrv[EEICA1_M24256E]->Init(M24256ECompObj[EEICA1_M24256E]) != M24_OK) { ret = BSP_ERROR_COMPONENT_FAILURE; } else { ret = BSP_ERROR_NONE; } return ret; } //------------------------------------------------------------------------------