Are you in need of an additional memory larger than EEPROM? Although EEPROM is a very easy and effective way of storing data on the board, the built in EEPROM only offers only a few bytes of storage. When working with larger or more advanced projects we may need to store additional data so an external memory solution. For that reason, MicroSD card enables you to do this quickly and easily. The following library provides a simple API to read/write sectors of the attached SD card in a STM32F779NI evaluation board.
/*! @file dev_sd.h @brief Copyright (C) 2017 Intelligent Systems & Computer Architecture Laboratory - T.E.I Crete http://isca.teicrete.gr This program is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation, either version 2.1 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this program. If not, see <http://www.gnu.org/licenses/>. Date: May 28, 2017 Version: 1 Design: Io. D Implementation: Io. D */ #ifdef __cplusplus extern "C" { #endif /****************************************************************************** * Header File Guard Symbol Start ******************************************************************************/ #ifndef DEV_SD_H_ /****************************************************************************** * Definitions ******************************************************************************/ #define DEV_SD_H_ /****************************************************************************** * Includes ******************************************************************************/ #include <Libraries/lbr_framework.h> #include "bsp_driver_sd.h" #include "sdmmc.h" /****************************************************************************** * Structures & Global Variables ******************************************************************************/ extern volatile uint32_t head_sector; extern volatile uint32_t tail_sector; extern volatile uint32_t SD_buffer_size; /****************************************************************************** * Static Variables ******************************************************************************/ /****************************************************************************** * Public Functions ******************************************************************************/ extern void SD_Init(); extern int SD_Read(uint32_t,uint8_t *,uint32_t); extern void SD_Append(uint8_t *,uint32_t); extern void SD_Clear(); extern void SD_Reset_Interface(); /****************************************************************************** * Static Functions ******************************************************************************/ /****************************************************************************** * Header File Guard Symbol End *******************************************************************************/ #endif #ifdef __cplusplus } #endif
/*! @file dev_sd.c @brief Copyright (C) 2017 Intelligent Systems & Computer Architecture Laboratory - T.E.I Crete http://isca.teicrete.gr This program is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation, either version 2.1 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this program. If not, see <http://www.gnu.org/licenses/>. Date: May 28, 2017 Version: 1 Design: Io. D Implementation: Io. D */ /****************************************************************************** * Source File Start ******************************************************************************/ #define SD_SECTOR_SIZE 512 /****************************************************************************** * Includes ******************************************************************************/ #include "FreeRTOS.h" #include "task.h" #include "cmsis_os.h" #include "dev_sd.h" /****************************************************************************** * Public Variables ******************************************************************************/ /****************************************************************************** * Static Variables ******************************************************************************/ volatile uint32_t head_sector = 0x00; volatile uint32_t tail_sector = 0x00; volatile uint8_t SD_buffer_Out[512]; volatile uint8_t SD_buffer_In[512]; volatile uint32_t SD_buffer_size =0x00; /****************************************************************************** * Public Functions ******************************************************************************/ void SD_Reset_Interface() { MX_SDMMC1_SD_Init(); BSP_SD_Init(); MX_FATFS_Init(); } void SD_Init() { MX_SDMMC1_SD_Init(); BSP_SD_Init(); MX_FATFS_Init(); memset(SD_buffer_Out,0,512); memset(SD_buffer_In,0,512); head_sector = 0; tail_sector = 0; SD_buffer_size = 0; } int SD_Read(uint32_t address,uint8_t *data,uint32_t size) { uint32_t remaining_data = size; uint32_t first_sector = address / SD_SECTOR_SIZE; uint32_t last_sector = (address + size) % SD_SECTOR_SIZE == 0 ? ((address + size) / SD_SECTOR_SIZE) - 1 : (address + size) / SD_SECTOR_SIZE; uint32_t current_sector = first_sector > tail_sector ? tail_sector : first_sector; uint32_t address_offset = address % SD_SECTOR_SIZE; uint32_t data_position = 0; last_sector = last_sector > tail_sector ? tail_sector : last_sector; for (current_sector = first_sector; current_sector < last_sector; current_sector++) { if(BSP_SD_ReadBlocks(SD_buffer_Out,current_sector,1,100)!=HAL_OK) { osDelay(10); SD_Reset_Interface(); osDelay(10); if(BSP_SD_ReadBlocks(SD_buffer_Out,current_sector,1,100)!=HAL_OK) return 0; } osDelay(10); memmove (&data[data_position], &SD_buffer_Out[address_offset], SD_SECTOR_SIZE - address_offset); remaining_data = remaining_data- (SD_SECTOR_SIZE - address_offset); data_position += (SD_SECTOR_SIZE - address_offset); address_offset = 0; } if (remaining_data != 0) { if (current_sector == tail_sector) { remaining_data = (remaining_data + (address_offset)) <= SD_buffer_size ? remaining_data : SD_buffer_size <= address_offset ? 0 : SD_buffer_size - address_offset; memmove (&data[data_position], &SD_buffer_In[address_offset], remaining_data); return data_position+remaining_data; } else if(current_sector<tail_sector) { if(BSP_SD_ReadBlocks(SD_buffer_Out,last_sector,1,100)!=HAL_OK) { osDelay(10); SD_Reset_Interface(); osDelay(10); if(BSP_SD_ReadBlocks(SD_buffer_Out,last_sector,1,100)!=HAL_OK) return 0; } osDelay(10); memmove (&data[data_position], &SD_buffer_Out[address_offset], remaining_data); return data_position + remaining_data; } return 0; } return data_position; } void SD_Append(uint8_t *data,uint32_t size) { uint32_t remaining_data = size; if (SD_buffer_size + size < SD_SECTOR_SIZE) { memmove (&SD_buffer_In[SD_buffer_size], data, size); SD_buffer_size = SD_buffer_size + size; return; } while (remaining_data != 0) { memmove (&SD_buffer_In[SD_buffer_size], &data[size -remaining_data], SD_SECTOR_SIZE - SD_buffer_size); BSP_SD_WriteBlocks (SD_buffer_In, tail_sector , 1, 100); osDelay (10); remaining_data = remaining_data - (SD_SECTOR_SIZE - SD_buffer_size); tail_sector++; SD_buffer_size = 0; osDelay (10); if (remaining_data == 0) break; if (remaining_data < SD_SECTOR_SIZE) { memset (SD_buffer_In, 0, SD_SECTOR_SIZE); memmove (&SD_buffer_In[0], data + (size - remaining_data), remaining_data); SD_buffer_size = remaining_data; remaining_data = 0; break; } } } void SD_Clear() { BSP_SD_Erase(0,8192); memset(SD_buffer_Out,0,512); memset(SD_buffer_In,0,512); head_sector = 0; tail_sector = 0; SD_buffer_size = 0; } /****************************************************************************** * Static Functions ******************************************************************************/ /****************************************************************************** * Source File End ******************************************************************************/