stm: Mount SD card on 1:/ if present.
If SD card is present on (soft) reset then it's mounted on 1:/ and files can be openned using, eg, open('1:/test.txt', 'r'), or 'w' for writing.
This commit is contained in:
parent
aea532ece1
commit
23177088d2
@ -58,7 +58,7 @@ SRC_C = \
|
||||
usb.c \
|
||||
timer.c \
|
||||
audio.c \
|
||||
sdio.c \
|
||||
sdcard.c \
|
||||
i2c.c \
|
||||
usrsw.c \
|
||||
adc.c \
|
||||
|
@ -13,20 +13,20 @@
|
||||
#include "diskio.h" /* FatFs lower layer API */
|
||||
#include "misc.h"
|
||||
#include "storage.h"
|
||||
#include "sdcard.h"
|
||||
|
||||
PARTITION VolToPart[] = {
|
||||
{0, 1}, // Logical drive 0 ==> Physical drive 0, 1st partition
|
||||
{1, 0}, // Logical drive 1 ==> Physical drive 1 (auto detection)
|
||||
/*
|
||||
{0, 2}, // Logical drive 1 ==> Physical drive 0, 2nd partition
|
||||
{0, 3}, // Logical drive 2 ==> Physical drive 0, 3rd partition
|
||||
{1, 0}, // Logical drive 3 ==> Physical drive 1 (auto detection)
|
||||
{0, 2}, // Logical drive 2 ==> Physical drive 0, 2nd partition
|
||||
{0, 3}, // Logical drive 3 ==> Physical drive 0, 3rd partition
|
||||
*/
|
||||
};
|
||||
|
||||
/* Definitions of physical drive number for each media */
|
||||
#define PD_FLASH (0)
|
||||
#define PD_SD (1)
|
||||
#define BLOCK_SIZE (512)
|
||||
#define PD_SDCARD (1)
|
||||
|
||||
/*-----------------------------------------------------------------------*/
|
||||
/* Initialize a Drive */
|
||||
@ -37,9 +37,16 @@ DSTATUS disk_initialize (
|
||||
)
|
||||
{
|
||||
switch (pdrv) {
|
||||
case PD_FLASH :
|
||||
case PD_FLASH:
|
||||
storage_init();
|
||||
return 0;
|
||||
|
||||
case PD_SDCARD:
|
||||
if (!sdcard_power_on()) {
|
||||
return STA_NODISK;
|
||||
}
|
||||
// TODO return STA_PROTECT if SD card is read only
|
||||
return 0;
|
||||
}
|
||||
|
||||
return STA_NOINIT;
|
||||
@ -58,8 +65,9 @@ DSTATUS disk_status (
|
||||
// flash is ready
|
||||
return 0;
|
||||
|
||||
case PD_SD:
|
||||
return STA_NOINIT;
|
||||
case PD_SDCARD:
|
||||
// TODO return STA_PROTECT if SD card is read only
|
||||
return 0;
|
||||
}
|
||||
|
||||
return STA_NOINIT;
|
||||
@ -79,7 +87,16 @@ DRESULT disk_read (
|
||||
switch (pdrv) {
|
||||
case PD_FLASH:
|
||||
for (int i = 0; i < count; i++) {
|
||||
if (!storage_read_block(buff + i * BLOCK_SIZE, sector + i)) {
|
||||
if (!storage_read_block(buff + i * FLASH_BLOCK_SIZE, sector + i)) {
|
||||
return RES_ERROR;
|
||||
}
|
||||
}
|
||||
return RES_OK;
|
||||
|
||||
case PD_SDCARD:
|
||||
// TODO have a multi-block read function
|
||||
for (int i = 0; i < count; i++) {
|
||||
if (!sdcard_read_block(buff + i * SDCARD_BLOCK_SIZE, sector + i)) {
|
||||
return RES_ERROR;
|
||||
}
|
||||
}
|
||||
@ -104,7 +121,16 @@ DRESULT disk_write (
|
||||
switch (pdrv) {
|
||||
case PD_FLASH:
|
||||
for (int i = 0; i < count; i++) {
|
||||
if (!storage_write_block(buff + i * BLOCK_SIZE, sector + i)) {
|
||||
if (!storage_write_block(buff + i * FLASH_BLOCK_SIZE, sector + i)) {
|
||||
return RES_ERROR;
|
||||
}
|
||||
}
|
||||
return RES_OK;
|
||||
|
||||
case PD_SDCARD:
|
||||
// TODO have a multi-block write function
|
||||
for (int i = 0; i < count; i++) {
|
||||
if (!sdcard_write_block(buff + i * SDCARD_BLOCK_SIZE, sector + i)) {
|
||||
return RES_ERROR;
|
||||
}
|
||||
}
|
||||
@ -138,6 +164,18 @@ DRESULT disk_ioctl (
|
||||
*((DWORD*)buff) = 1; // high-level sector erase size in units of the small (512) block size
|
||||
return RES_OK;
|
||||
}
|
||||
break;
|
||||
|
||||
case PD_SDCARD:
|
||||
switch (cmd) {
|
||||
case CTRL_SYNC:
|
||||
return RES_OK;
|
||||
|
||||
case GET_BLOCK_SIZE:
|
||||
*((DWORD*)buff) = 1; // high-level sector erase size in units of the small (512) block size
|
||||
return RES_OK;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
return RES_PARERR;
|
||||
@ -148,6 +186,7 @@ DWORD get_fattime (
|
||||
void
|
||||
)
|
||||
{
|
||||
// TODO replace with call to RTC
|
||||
int year = 2013;
|
||||
int month = 10;
|
||||
int day = 12;
|
||||
|
@ -136,7 +136,7 @@
|
||||
/ Drive/Volume Configurations
|
||||
/----------------------------------------------------------------------------*/
|
||||
|
||||
#define _VOLUMES 1
|
||||
#define _VOLUMES 2
|
||||
/* Number of volumes (logical drives) to be used. */
|
||||
|
||||
|
||||
|
26
stm/main.c
26
stm/main.c
@ -35,6 +35,7 @@
|
||||
#include "servo.h"
|
||||
#include "lcd.h"
|
||||
#include "storage.h"
|
||||
#include "sdcard.h"
|
||||
#include "mma.h"
|
||||
#include "usart.h"
|
||||
#include "usb.h"
|
||||
@ -50,6 +51,7 @@
|
||||
int errno;
|
||||
|
||||
static FATFS fatfs0;
|
||||
static FATFS fatfs1;
|
||||
|
||||
void flash_error(int n) {
|
||||
for (int i = 0; i < n; i++) {
|
||||
@ -224,15 +226,6 @@ static mp_obj_t pyb_set_repl_info(mp_obj_t o_value) {
|
||||
return mp_const_none;
|
||||
}
|
||||
|
||||
#if MICROPY_HW_HAS_SDCARD
|
||||
// SD card test
|
||||
static mp_obj_t pyb_sd_test(void) {
|
||||
extern void sdio_init(void);
|
||||
sdio_init();
|
||||
return mp_const_none;
|
||||
}
|
||||
#endif
|
||||
|
||||
static void SYSCLKConfig_STOP(void) {
|
||||
/* After wake-up from STOP reconfigure the system clock */
|
||||
/* Enable HSE */
|
||||
@ -639,6 +632,9 @@ int main(void) {
|
||||
// more sub-system init
|
||||
#if MICROPY_HW_HAS_SWITCH
|
||||
switch_init();
|
||||
#endif
|
||||
#if MICROPY_HW_HAS_SDCARD
|
||||
sdcard_init();
|
||||
#endif
|
||||
storage_init();
|
||||
|
||||
@ -692,7 +688,7 @@ soft_reset:
|
||||
rt_store_attr(m, MP_QSTR_gc, (mp_obj_t)&pyb_gc_obj);
|
||||
rt_store_attr(m, qstr_from_str("repl_info"), rt_make_function_n(1, pyb_set_repl_info));
|
||||
#if MICROPY_HW_HAS_SDCARD
|
||||
rt_store_attr(m, MP_QSTR_sd_test, rt_make_function_n(0, pyb_sd_test));
|
||||
rt_store_attr(m, qstr_from_str("SD"), (mp_obj_t)&pyb_sdcard_obj);
|
||||
#endif
|
||||
rt_store_attr(m, MP_QSTR_stop, rt_make_function_n(0, pyb_stop));
|
||||
rt_store_attr(m, MP_QSTR_standby, rt_make_function_n(0, pyb_standby));
|
||||
@ -844,6 +840,16 @@ soft_reset:
|
||||
// turn boot-up LED off
|
||||
led_state(PYB_LED_G1, 0);
|
||||
|
||||
#if MICROPY_HW_HAS_SDCARD
|
||||
// if an SD card is present then mount it on 1:/
|
||||
if (sdcard_is_present()) {
|
||||
FRESULT res = f_mount(&fatfs1, "1:", 1);
|
||||
if (res != FR_OK) {
|
||||
printf("[SD] could not mount SD card\n");
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
// run main script
|
||||
{
|
||||
vstr_t *vstr = vstr_new();
|
||||
|
204
stm/sdcard.c
Normal file
204
stm/sdcard.c
Normal file
@ -0,0 +1,204 @@
|
||||
// TODO
|
||||
// make it work with DMA
|
||||
|
||||
#include <stdio.h>
|
||||
//#include "stm32f4xx_sdio.h"
|
||||
#include "stm324x7i_eval_sdio_sd.h"
|
||||
#include "misc.h"
|
||||
#include "systick.h"
|
||||
#include "mpconfig.h"
|
||||
#include "qstr.h"
|
||||
#include "obj.h"
|
||||
#include "runtime.h"
|
||||
#include "sdcard.h"
|
||||
|
||||
#if 0
|
||||
#define BLOCK_SIZE 512 /* Block Size in Bytes */
|
||||
|
||||
uint8_t aBuffer_Block_Rx[BLOCK_SIZE];
|
||||
|
||||
void sdio_init(void) {
|
||||
SD_Error error = SD_Init();
|
||||
printf("Init: %x\n", error);
|
||||
uint8_t det = SD_Detect();
|
||||
printf("Detc: %x\n", det);
|
||||
|
||||
if (!det) {
|
||||
printf("no card detected\n");
|
||||
SD_PowerOFF();
|
||||
SD_DeInit();
|
||||
return;
|
||||
}
|
||||
|
||||
// read a block!
|
||||
error = SD_ReadBlock(aBuffer_Block_Rx, 512, BLOCK_SIZE);
|
||||
printf("ReadBlock: %d\n", error);
|
||||
|
||||
/*
|
||||
// Check if the Transfer is finished
|
||||
error = SD_WaitReadOperation();
|
||||
printf("WaitReadOp: %d\n", error);
|
||||
*/
|
||||
|
||||
uint32_t stc = sys_tick_counter;
|
||||
while (SD_GetStatus() != SD_TRANSFER_OK) {
|
||||
if (sys_tick_has_passed(stc, 2000)) {
|
||||
printf("timeout waiting for read to finish\n");
|
||||
break;
|
||||
}
|
||||
}
|
||||
printf("done!!\n");
|
||||
|
||||
printf("%.16s", aBuffer_Block_Rx);
|
||||
|
||||
/*
|
||||
snprintf((char*)aBuffer_Block_Rx, BLOCK_SIZE, "Here is some data back for you!\nBLOCK_SIZE=%d\n", BLOCK_SIZE);
|
||||
error = SD_WriteBlock(aBuffer_Block_Rx, 512, BLOCK_SIZE);
|
||||
printf("WriteBlock: %d\n", error);
|
||||
|
||||
while (SD_GetStatus() != SD_TRANSFER_OK) {
|
||||
}
|
||||
printf("done writing!\n");
|
||||
*/
|
||||
|
||||
SD_PowerOFF();
|
||||
SD_DeInit();
|
||||
}
|
||||
#endif
|
||||
|
||||
void sdcard_init(void) {
|
||||
// init the SD card detect pin
|
||||
SD_LowLevel_Init_Detect();
|
||||
}
|
||||
|
||||
bool sdcard_is_present(void) {
|
||||
return SD_Detect() != 0;
|
||||
}
|
||||
|
||||
bool sdcard_power_on(void) {
|
||||
if (!SD_Detect()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
SD_Error status = SD_Init();
|
||||
if (status != SD_OK) {
|
||||
SD_PowerOFF();
|
||||
SD_DeInit();
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void sdcard_power_off(void) {
|
||||
SD_PowerOFF();
|
||||
SD_DeInit();
|
||||
}
|
||||
|
||||
bool sdcard_read_block(uint8_t *dest, uint32_t block_num) {
|
||||
// TODO return error if not powered on
|
||||
|
||||
SD_Error status;
|
||||
|
||||
status = SD_ReadBlock(dest, block_num * SDCARD_BLOCK_SIZE, SDCARD_BLOCK_SIZE);
|
||||
if (status != SD_OK) {
|
||||
return false;
|
||||
}
|
||||
|
||||
#ifdef SD_DMA_MODE
|
||||
// wait for DMA transfer to finish
|
||||
status = SD_WaitReadOperation();
|
||||
if (status != SD_OK) {
|
||||
return false;
|
||||
}
|
||||
#endif
|
||||
|
||||
// wait for SD controller to finish
|
||||
uint32_t stc = sys_tick_counter;
|
||||
while (SD_GetStatus() != SD_TRANSFER_OK) {
|
||||
if (sys_tick_has_passed(stc, 5000)) {
|
||||
//printf("[ERROR] timeout waiting for SD card read to finish\n");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool sdcard_write_block(const uint8_t *src, uint32_t block_num) {
|
||||
// TODO return error if not powered on
|
||||
|
||||
SD_Error status;
|
||||
|
||||
status = SD_WriteBlock((uint8_t*)src, block_num * SDCARD_BLOCK_SIZE, SDCARD_BLOCK_SIZE);
|
||||
if (status != SD_OK) {
|
||||
return false;
|
||||
}
|
||||
|
||||
#ifdef SD_DMA_MODE
|
||||
// wait for DMA transfer to finish
|
||||
status = SD_WaitReadOperation();
|
||||
if (status != SD_OK) {
|
||||
return false;
|
||||
}
|
||||
#endif
|
||||
|
||||
// wait for SD controller to finish
|
||||
uint32_t stc = sys_tick_counter;
|
||||
while (SD_GetStatus() != SD_TRANSFER_OK) {
|
||||
if (sys_tick_has_passed(stc, 5000)) {
|
||||
//printf("[ERROR] timeout waiting for SD card write to finish\n");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/******************************************************************************/
|
||||
// Micro Python bindings
|
||||
|
||||
static mp_obj_t sd_present(mp_obj_t self) {
|
||||
return MP_BOOL(sdcard_is_present());
|
||||
}
|
||||
|
||||
static MP_DEFINE_CONST_FUN_OBJ_1(sd_present_obj, sd_present);
|
||||
|
||||
static mp_obj_t sd_power(mp_obj_t self, mp_obj_t state) {
|
||||
bool result;
|
||||
if (rt_is_true(state)) {
|
||||
result = sdcard_power_on();
|
||||
} else {
|
||||
sdcard_power_off();
|
||||
result = true;
|
||||
}
|
||||
return MP_BOOL(result);
|
||||
}
|
||||
|
||||
static MP_DEFINE_CONST_FUN_OBJ_2(sd_power_obj, sd_power);
|
||||
|
||||
static mp_obj_t sd_read(mp_obj_t self, mp_obj_t block_num) {
|
||||
uint8_t *dest = m_new(uint8_t, SDCARD_BLOCK_SIZE);
|
||||
if (!sdcard_read_block(dest, mp_obj_get_int(block_num))) {
|
||||
m_free(dest, SDCARD_BLOCK_SIZE);
|
||||
return mp_const_none;
|
||||
}
|
||||
return mp_obj_new_bytearray_by_ref(SDCARD_BLOCK_SIZE, dest);
|
||||
}
|
||||
|
||||
static MP_DEFINE_CONST_FUN_OBJ_2(sd_read_obj, sd_read);
|
||||
|
||||
static const mp_method_t sdcard_methods[] = {
|
||||
{ "present", &sd_present_obj },
|
||||
{ "power", &sd_power_obj },
|
||||
{ "read", &sd_read_obj },
|
||||
{ NULL, NULL },
|
||||
};
|
||||
|
||||
static const mp_obj_type_t sdcard_type = {
|
||||
{ &mp_const_type },
|
||||
"SDcard",
|
||||
.methods = sdcard_methods,
|
||||
};
|
||||
|
||||
const mp_obj_base_t pyb_sdcard_obj = {&sdcard_type};
|
11
stm/sdcard.h
Normal file
11
stm/sdcard.h
Normal file
@ -0,0 +1,11 @@
|
||||
// this is a fixed size and should not be changed
|
||||
#define SDCARD_BLOCK_SIZE (512)
|
||||
|
||||
void sdcard_init(void);
|
||||
bool sdcard_is_present(void);
|
||||
bool sdcard_power_on(void);
|
||||
void sdcard_power_off(void);
|
||||
bool sdcard_read_block(uint8_t *dest, uint32_t block_num);
|
||||
bool sdcard_write_block(const uint8_t *src, uint32_t block_num);
|
||||
|
||||
extern const struct _mp_obj_base_t pyb_sdcard_obj;
|
60
stm/sdio.c
60
stm/sdio.c
@ -1,60 +0,0 @@
|
||||
// TODO
|
||||
// make it work with DMA
|
||||
|
||||
#include <stdio.h>
|
||||
//#include "stm32f4xx_sdio.h"
|
||||
#include "stm324x7i_eval_sdio_sd.h"
|
||||
#include "misc.h"
|
||||
#include "systick.h"
|
||||
|
||||
#define BLOCK_SIZE 512 /* Block Size in Bytes */
|
||||
|
||||
uint8_t aBuffer_Block_Rx[BLOCK_SIZE];
|
||||
|
||||
void sdio_init(void) {
|
||||
SD_Error error = SD_Init();
|
||||
printf("Init: %x\n", error);
|
||||
uint8_t det = SD_Detect();
|
||||
printf("Detc: %x\n", det);
|
||||
|
||||
if (!det) {
|
||||
printf("no card detected\n");
|
||||
SD_PowerOFF();
|
||||
SD_DeInit();
|
||||
return;
|
||||
}
|
||||
|
||||
// read a block!
|
||||
error = SD_ReadBlock(aBuffer_Block_Rx, 512, BLOCK_SIZE);
|
||||
printf("ReadBlock: %d\n", error);
|
||||
|
||||
/*
|
||||
// Check if the Transfer is finished
|
||||
error = SD_WaitReadOperation();
|
||||
printf("WaitReadOp: %d\n", error);
|
||||
*/
|
||||
|
||||
uint32_t stc = sys_tick_counter;
|
||||
while (SD_GetStatus() != SD_TRANSFER_OK) {
|
||||
if (sys_tick_has_passed(stc, 2000)) {
|
||||
printf("timeout waiting for read to finish\n");
|
||||
break;
|
||||
}
|
||||
}
|
||||
printf("done!!\n");
|
||||
|
||||
printf("%.16s", aBuffer_Block_Rx);
|
||||
|
||||
/*
|
||||
snprintf((char*)aBuffer_Block_Rx, BLOCK_SIZE, "Here is some data back for you!\nBLOCK_SIZE=%d\n", BLOCK_SIZE);
|
||||
error = SD_WriteBlock(aBuffer_Block_Rx, 512, BLOCK_SIZE);
|
||||
printf("WriteBlock: %d\n", error);
|
||||
|
||||
while (SD_GetStatus() != SD_TRANSFER_OK) {
|
||||
}
|
||||
printf("done writing!\n");
|
||||
*/
|
||||
|
||||
SD_PowerOFF();
|
||||
SD_DeInit();
|
||||
}
|
@ -84,6 +84,34 @@ void SD_LowLevel_DeInit(void)
|
||||
GPIO_Init(GPIOC, &GPIO_InitStructure);
|
||||
}
|
||||
|
||||
/* Init just the detect pin.
|
||||
* This is so we can save power by not enabling the whole SD card interface,
|
||||
* yet still detect when a card is inserted.
|
||||
*/
|
||||
void SD_LowLevel_Init_Detect(void) {
|
||||
GPIO_InitTypeDef GPIO_InitStructure;
|
||||
|
||||
/* Periph clock enable */
|
||||
RCC_AHB1PeriphClockCmd(SD_DETECT_GPIO_CLK, ENABLE);
|
||||
|
||||
/*!< Configure SD_SPI_DETECT_PIN pin: SD Card detect pin */
|
||||
#if defined(PYBOARD3)
|
||||
// dpgeorge: PYBv2-v3: switch is normally open, connected to VDD when card inserted
|
||||
GPIO_InitStructure.GPIO_Pin = SD_DETECT_PIN;
|
||||
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_2MHz; // needs to be 2MHz due to restrictions on PC13
|
||||
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN;
|
||||
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_DOWN;
|
||||
GPIO_Init(SD_DETECT_GPIO_PORT, &GPIO_InitStructure);
|
||||
#elif defined(PYBOARD4)
|
||||
// dpgeorge: PYBv4: switch is normally open, connected to GND when card inserted
|
||||
GPIO_InitStructure.GPIO_Pin = SD_DETECT_PIN;
|
||||
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_2MHz;
|
||||
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN;
|
||||
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP;
|
||||
GPIO_Init(SD_DETECT_GPIO_PORT, &GPIO_InitStructure);
|
||||
#endif
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Initializes the SD Card and put it into StandBy State (Ready for
|
||||
* data transfer).
|
||||
@ -92,6 +120,9 @@ void SD_LowLevel_DeInit(void)
|
||||
*/
|
||||
void SD_LowLevel_Init(void)
|
||||
{
|
||||
// init the detect pin first
|
||||
SD_LowLevel_Init_Detect();
|
||||
|
||||
GPIO_InitTypeDef GPIO_InitStructure;
|
||||
|
||||
/* GPIOC and GPIOD Periph clock enable */
|
||||
@ -120,23 +151,6 @@ void SD_LowLevel_Init(void)
|
||||
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_12;
|
||||
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;
|
||||
GPIO_Init(GPIOC, &GPIO_InitStructure);
|
||||
|
||||
/*!< Configure SD_SPI_DETECT_PIN pin: SD Card detect pin */
|
||||
#if defined(PYBOARD3)
|
||||
// dpgeorge: PYBv2-v3: switch is normally open, connected to VDD when card inserted
|
||||
GPIO_InitStructure.GPIO_Pin = SD_DETECT_PIN;
|
||||
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_2MHz; // needs to be 2MHz due to restrictions on PC13
|
||||
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN;
|
||||
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_DOWN;
|
||||
GPIO_Init(SD_DETECT_GPIO_PORT, &GPIO_InitStructure);
|
||||
#elif defined(PYBOARD4)
|
||||
// dpgeorge: PYBv4: switch is normally open, connected to GND when card inserted
|
||||
GPIO_InitStructure.GPIO_Pin = SD_DETECT_PIN;
|
||||
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_2MHz;
|
||||
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN;
|
||||
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP;
|
||||
GPIO_Init(SD_DETECT_GPIO_PORT, &GPIO_InitStructure);
|
||||
#endif
|
||||
|
||||
/* Enable the SDIO APB2 Clock */
|
||||
RCC_APB2PeriphClockCmd(RCC_APB2Periph_SDIO, ENABLE);
|
||||
|
@ -103,7 +103,8 @@
|
||||
* @{
|
||||
*/
|
||||
void SD_LowLevel_DeInit(void);
|
||||
void SD_LowLevel_Init(void);
|
||||
void SD_LowLevel_Init_Detect(void);
|
||||
void SD_LowLevel_Init(void);
|
||||
void SD_LowLevel_DMA_TxConfig(uint32_t *BufferSRC, uint32_t BufferSize);
|
||||
void SD_LowLevel_DMA_RxConfig(uint32_t *BufferDST, uint32_t BufferSize);
|
||||
|
||||
|
@ -10,51 +10,50 @@
|
||||
#include "flash.h"
|
||||
#include "storage.h"
|
||||
|
||||
#define BLOCK_SIZE (512)
|
||||
#define CACHE_MEM_START_ADDR (0x10000000) // CCM data RAM, 64k
|
||||
#define FLASH_PART1_START_BLOCK (0x100)
|
||||
#define FLASH_PART1_NUM_BLOCKS (224) // 16k+16k+16k+64k=112k
|
||||
#define FLASH_MEM_START_ADDR (0x08004000) // sector 1, 16k
|
||||
|
||||
static bool is_initialised = false;
|
||||
static uint32_t cache_flash_sector_id;
|
||||
static uint32_t cache_flash_sector_start;
|
||||
static uint32_t cache_flash_sector_size;
|
||||
static bool cache_dirty;
|
||||
static uint32_t sys_tick_counter_last_write;
|
||||
static bool flash_is_initialised = false;
|
||||
static bool flash_cache_dirty;
|
||||
static uint32_t flash_cache_sector_id;
|
||||
static uint32_t flash_cache_sector_start;
|
||||
static uint32_t flash_cache_sector_size;
|
||||
static uint32_t flash_sys_tick_counter_last_write;
|
||||
|
||||
static void cache_flush(void) {
|
||||
if (cache_dirty) {
|
||||
static void flash_cache_flush(void) {
|
||||
if (flash_cache_dirty) {
|
||||
// sync the cache RAM buffer by writing it to the flash page
|
||||
flash_write(cache_flash_sector_start, (const uint32_t*)CACHE_MEM_START_ADDR, cache_flash_sector_size / 4);
|
||||
cache_dirty = false;
|
||||
flash_write(flash_cache_sector_start, (const uint32_t*)CACHE_MEM_START_ADDR, flash_cache_sector_size / 4);
|
||||
flash_cache_dirty = false;
|
||||
// indicate a clean cache with LED off
|
||||
led_state(PYB_LED_R1, 0);
|
||||
}
|
||||
}
|
||||
|
||||
static uint8_t *cache_get_addr_for_write(uint32_t flash_addr) {
|
||||
static uint8_t *flash_cache_get_addr_for_write(uint32_t flash_addr) {
|
||||
uint32_t flash_sector_start;
|
||||
uint32_t flash_sector_size;
|
||||
uint32_t flash_sector_id = flash_get_sector_info(flash_addr, &flash_sector_start, &flash_sector_size);
|
||||
if (cache_flash_sector_id != flash_sector_id) {
|
||||
cache_flush();
|
||||
if (flash_cache_sector_id != flash_sector_id) {
|
||||
flash_cache_flush();
|
||||
memcpy((void*)CACHE_MEM_START_ADDR, (const void*)flash_sector_start, flash_sector_size);
|
||||
cache_flash_sector_id = flash_sector_id;
|
||||
cache_flash_sector_start = flash_sector_start;
|
||||
cache_flash_sector_size = flash_sector_size;
|
||||
flash_cache_sector_id = flash_sector_id;
|
||||
flash_cache_sector_start = flash_sector_start;
|
||||
flash_cache_sector_size = flash_sector_size;
|
||||
}
|
||||
cache_dirty = true;
|
||||
flash_cache_dirty = true;
|
||||
// indicate a dirty cache with LED on
|
||||
led_state(PYB_LED_R1, 1);
|
||||
return (uint8_t*)CACHE_MEM_START_ADDR + flash_addr - flash_sector_start;
|
||||
}
|
||||
|
||||
static uint8_t *cache_get_addr_for_read(uint32_t flash_addr) {
|
||||
static uint8_t *flash_cache_get_addr_for_read(uint32_t flash_addr) {
|
||||
uint32_t flash_sector_start;
|
||||
uint32_t flash_sector_size;
|
||||
uint32_t flash_sector_id = flash_get_sector_info(flash_addr, &flash_sector_start, &flash_sector_size);
|
||||
if (cache_flash_sector_id == flash_sector_id) {
|
||||
if (flash_cache_sector_id == flash_sector_id) {
|
||||
// in cache, copy from there
|
||||
return (uint8_t*)CACHE_MEM_START_ADDR + flash_addr - flash_sector_start;
|
||||
}
|
||||
@ -63,16 +62,16 @@ static uint8_t *cache_get_addr_for_read(uint32_t flash_addr) {
|
||||
}
|
||||
|
||||
void storage_init(void) {
|
||||
if (!is_initialised) {
|
||||
cache_flash_sector_id = 0;
|
||||
cache_dirty = false;
|
||||
is_initialised = true;
|
||||
sys_tick_counter_last_write = 0;
|
||||
if (!flash_is_initialised) {
|
||||
flash_cache_dirty = false;
|
||||
flash_cache_sector_id = 0;
|
||||
flash_is_initialised = true;
|
||||
flash_sys_tick_counter_last_write = 0;
|
||||
}
|
||||
}
|
||||
|
||||
uint32_t storage_get_block_size(void) {
|
||||
return BLOCK_SIZE;
|
||||
return FLASH_BLOCK_SIZE;
|
||||
}
|
||||
|
||||
uint32_t storage_get_block_count(void) {
|
||||
@ -81,11 +80,11 @@ uint32_t storage_get_block_count(void) {
|
||||
|
||||
bool storage_needs_flush(void) {
|
||||
// wait 2 seconds after last write to flush
|
||||
return cache_dirty && sys_tick_has_passed(sys_tick_counter_last_write, 2000);
|
||||
return flash_cache_dirty && sys_tick_has_passed(flash_sys_tick_counter_last_write, 2000);
|
||||
}
|
||||
|
||||
void storage_flush(void) {
|
||||
cache_flush();
|
||||
flash_cache_flush();
|
||||
}
|
||||
|
||||
static void build_partition(uint8_t *buf, int boot, int type, uint32_t start_block, uint32_t num_blocks) {
|
||||
@ -145,9 +144,9 @@ bool storage_read_block(uint8_t *dest, uint32_t block) {
|
||||
|
||||
} else if (FLASH_PART1_START_BLOCK <= block && block < FLASH_PART1_START_BLOCK + FLASH_PART1_NUM_BLOCKS) {
|
||||
// non-MBR block, get data from flash memory, possibly via cache
|
||||
uint32_t flash_addr = FLASH_MEM_START_ADDR + (block - FLASH_PART1_START_BLOCK) * BLOCK_SIZE;
|
||||
uint8_t *src = cache_get_addr_for_read(flash_addr);
|
||||
memcpy(dest, src, BLOCK_SIZE);
|
||||
uint32_t flash_addr = FLASH_MEM_START_ADDR + (block - FLASH_PART1_START_BLOCK) * FLASH_BLOCK_SIZE;
|
||||
uint8_t *src = flash_cache_get_addr_for_read(flash_addr);
|
||||
memcpy(dest, src, FLASH_BLOCK_SIZE);
|
||||
return true;
|
||||
|
||||
} else {
|
||||
@ -164,10 +163,10 @@ bool storage_write_block(const uint8_t *src, uint32_t block) {
|
||||
|
||||
} else if (FLASH_PART1_START_BLOCK <= block && block < FLASH_PART1_START_BLOCK + FLASH_PART1_NUM_BLOCKS) {
|
||||
// non-MBR block, copy to cache
|
||||
uint32_t flash_addr = FLASH_MEM_START_ADDR + (block - FLASH_PART1_START_BLOCK) * BLOCK_SIZE;
|
||||
uint8_t *dest = cache_get_addr_for_write(flash_addr);
|
||||
memcpy(dest, src, BLOCK_SIZE);
|
||||
sys_tick_counter_last_write = sys_tick_counter;
|
||||
uint32_t flash_addr = FLASH_MEM_START_ADDR + (block - FLASH_PART1_START_BLOCK) * FLASH_BLOCK_SIZE;
|
||||
uint8_t *dest = flash_cache_get_addr_for_write(flash_addr);
|
||||
memcpy(dest, src, FLASH_BLOCK_SIZE);
|
||||
flash_sys_tick_counter_last_write = sys_tick_counter;
|
||||
return true;
|
||||
|
||||
} else {
|
||||
|
@ -1,3 +1,5 @@
|
||||
#define FLASH_BLOCK_SIZE (512)
|
||||
|
||||
void storage_init(void);
|
||||
uint32_t storage_get_block_size(void);
|
||||
uint32_t storage_get_block_count(void);
|
||||
|
Loading…
x
Reference in New Issue
Block a user