Помощь - Поиск - Пользователи - Календарь
Полная версия этой страницы: STM32F217&FATFS
Форум разработчиков электроники ELECTRONIX.ru > Микроконтроллеры (MCs) > ARM
ReRayne
Имеется отладочная плата Starterkit ST-STM32F217.
Последняя версия библиотеки FATFS, взятая отсюда.
Keil uVision 4 в качестве среды.
JetLink8 программатор.
SD на 4Gb.

Собственно в документации к FATFS написано, что в diskio.c надо реализовать I/O уровень.
Реализовала.
На чтение FATFS работает прекрасно.

А вот на записи начинается абсолютно непонятный мне космос.
Если выполнить f_write без отладчика, кидает FR_DISK_ERR и отваливается.
Если с отладчиком если пошагово трасировать f_write, записывает все, f_eof говорит, что файл имеет метку окончания, f_size отдает правильный размер, но когда вставляю в компьютер, машина сообщает, что файл битый.
Бьюсь уже который час, святые макароны знают, в чем дело.
SD_DMA_MODE закоменчен, раскоменчен SD_POLLING_MODE.

Собственно, discio.c
CODE
/*-----------------------------------------------------------------------*/
/* Low level disk I/O module skeleton for FatFs ©ChaN, 2007 */
/*-----------------------------------------------------------------------*/
/* by grqd_xp */
/* This is a stub disk I/O module that acts as front end of the existing */
/* disk I/O modules and attach it to FatFs module with common interface. */
/*-----------------------------------------------------------------------*/
/* by nemui trinomius */
/* adopted to STM32F2xx_StdPeriph_Driver V1.0.0. */
/*-----------------------------------------------------------------------*/
#include <string.h>
#include <stdio.h>
#include "stm32_eval_sdio_sd.h"
#include "diskio.h"

/*-----------------------------------------------------------------------*/
/* Correspondence between physical drive number and physical drive. */
/* Note that Tiny-FatFs supports only single drive and always */
/* accesses drive number 0. */

#define SECTOR_SIZE 512

static SD_Error Status = SD_OK;
static SD_CardInfo SDCardInfo;

/*-----------------------------------------------------------------------*/
/* Correspondence between physical drive number and physical drive. */
#define SDIO_DRIVE 0


/*-----------------------------------------------------------------------*/
/* Initialize a Drive */

DSTATUS disk_initialize (
BYTE drv /* Physical drive nmuber (0..) */
)
{
switch (drv)
{
case SDIO_DRIVE:
{
/* Initialize SD Card */
Status = SD_Init();

if (Status != SD_OK)
return STA_NOINIT;
else
return 0x00;
}
}

return STA_NOINIT;

}



/*-----------------------------------------------------------------------*/
/* Return Disk Status */

DSTATUS disk_status (
BYTE drv /* Physical drive nmuber (0..) */
)
{
switch (drv)
{
case SDIO_DRIVE:
{
Status = SD_GetCardInfo(&SDCardInfo);

if (Status != SD_OK)
return STA_NOINIT;
else
return 0x00;
}
}

return STA_NOINIT;
}



/*-----------------------------------------------------------------------*/
/* Read Sector(s) */
DRESULT disk_read (
BYTE drv, /* Physical drive nmuber (0..) */
BYTE *buff, /* Data buffer to store read data */
DWORD sector, /* Sector address (LBA) */
BYTE count /* Number of sectors to read (1..255) */
)
{
switch (drv)
{
case SDIO_DRIVE:
{
Status = SD_OK;

#if defined(SD_DMA_MODE) /* DMA Transfer */
/* Read Multiple Blocks */
Status = SD_ReadMultiBlocks((uint8_t*)(buff),(sector)*SECTOR_SIZE,SECTOR_SIZE,count);

/* Check if the Transfer is finished */
Status = SD_WaitReadOperation();

/* Wait until end of DMA transfer */
while(SD_GetStatus() != SD_TRANSFER_OK);

#else /* Polling Transfer */
for (int secNum = 0; (secNum < count) && (Status == SD_OK); secNum++)
{
Status = SD_ReadBlock((buff+SECTOR_SIZE*secNum),
(sector+secNum)*SECTOR_SIZE,
SECTOR_SIZE);
}
#endif

if (Status == SD_OK) return RES_OK;
else return RES_ERROR;
}

}
return RES_PARERR;
}



/*-----------------------------------------------------------------------*/
/* Write Sector(s) */

#if _READONLY == 0
DRESULT disk_write (
BYTE drv, /* Physical drive nmuber (0..) */
const BYTE *buff, /* Data to be written */
DWORD sector, /* Sector address (LBA) */
BYTE count /* Number of sectors to write (1..255) */
)
{
switch (drv)
{
case SDIO_DRIVE:
{
Status = SD_OK;

#if defined(SD_DMA_MODE) /* DMA Transfer */
/* Write Multiple Blocks */
Status = SD_WriteMultiBlocks((uint8_t*)(buff),(sector)*SECTOR_SIZE,SECTOR_SIZE,count);

/* Check if the Transfer is finished */
Status = SD_WaitWriteOperation();

/* Wait until end of DMA transfer */
while(SD_GetStatus() != SD_TRANSFER_OK);

#else /* Polling Transfer */
for (int secNum = 0; (secNum < count) && (Status == SD_OK); secNum++)
{
Status = SD_WriteBlock((uint8_t *) buff+SECTOR_SIZE*secNum,
(sector+secNum)*SECTOR_SIZE,
SECTOR_SIZE);
}

#endif

if (Status == SD_OK) return RES_OK;
else return RES_ERROR;
}

}
return RES_PARERR;
}
#endif /* _READONLY */



/*-----------------------------------------------------------------------*/
/* Miscellaneous Functions */

DRESULT disk_ioctl (
BYTE drv, /* Physical drive nmuber (0..) */
BYTE ctrl, /* Control code */
void *buff /* Buffer to send/receive control data */
)
{
switch (drv)
{
case SDIO_DRIVE:
{
switch (ctrl)
{
case CTRL_SYNC:
/* no synchronization to do since not buffering in this module */
return RES_OK;
case GET_SECTOR_SIZE:
*(WORD*)buff = SECTOR_SIZE;
return RES_OK;
case GET_SECTOR_COUNT:
*(DWORD*)buff = SDCardInfo.CardCapacity / SECTOR_SIZE;
return RES_OK;
case GET_BLOCK_SIZE:
*(DWORD*)buff = SECTOR_SIZE;
return RES_OK;
}
}
}
return RES_PARERR;
}

DWORD get_fattime (void)
{
DWORD res;
RTC_TimeTypeDef RTC_TimeStructure;
RTC_DateTypeDef RTC_DateStructure;

RTC_GetTime(RTC_Format_BIN, &RTC_TimeStructure);
RTC_GetDate(RTC_Format_BIN, &RTC_DateStructure);

res = (((DWORD)RTC_DateStructure.RTC_Year + 20) << 25)
| ((DWORD)RTC_DateStructure.RTC_Month << 21)
| ((DWORD)RTC_DateStructure.RTC_Date << 16)
| (WORD)(RTC_TimeStructure.RTC_Hours << 11)
| (WORD)(RTC_TimeStructure.RTC_Minutes << 5)
| (WORD)(RTC_TimeStructure.RTC_Seconds >> 1);

return res;
}


И main.c:
CODE
int main(void)
{
USART_InitStructure.USART_BaudRate = 115200;
USART_InitStructure.USART_WordLength = USART_WordLength_8b;
USART_InitStructure.USART_StopBits = USART_StopBits_1;
USART_InitStructure.USART_Parity = USART_Parity_No;
USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;
USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx;

STM_EVAL_COMInit(COM1, &USART_InitStructure);

Init_RTC();

/* Output a message on Hyperterminal using printf function */
printf("\n\rTest FATFS Lib for STM32F217\n\r");

fStatus = f_mount(DISC_LOGIC_NUMB, &fatfs);

printf("f_mount result: %i\r\n", fStatus);

if (fStatus == 0x00)
{
printf("Test read file.\r\n");

fStatus = f_open(&f, "test1.txt", FA_OPEN_EXISTING | FA_READ);

printf("f_open result: %i\r\n", fStatus);

if (fStatus == 0)
{
printf("f_size result: %i\r\n", f_size(&f));

char p[f_size(&f) + 1];
memset(p, 0, f_size(&f) + 1);

fStatus = f_read(&f, (void *) p, f_size(&f), &uiStatus);

printf("f_read result: fStatus: %i; uiStatus: %i;\r\n", fStatus, uiStatus);

fStatus = f_close(&f);

if (uiStatus > 0)
{
printf("Read data: %s\r\n", p);

printf("f_close result: %i\r\n", fStatus);

printf("Test write file.\r\n");

fStatus = f_open(&f, "0:test2.txt", FA_CREATE_ALWAYS | FA_WRITE);

printf("f_open result: %i\r\n", fStatus);

if (fStatus == 0)
{
printf("f_size result: %i\r\n", f_size(&f));

fStatus = f_write(&f, "Hello world!\r\n", strlen("Hello world!\r\n") + 1, &uiStatus);

printf("f_write result: fStatus: %i; uiStatus: %i;\r\n", fStatus, uiStatus);

printf("f_eof result: %i.\r\n", f_eof(&f));

if (fStatus > 0)
{
fStatus = f_unlink("test2.txt");

printf("f_ulink result: %i\r\n", fStatus);
}

printf("f_size result: %i\r\n", f_size(&f));
}

f_sync(&f);
fStatus = f_close(&f);
}

fStatus = f_mount(DISC_LOGIC_NUMB, NULL);

printf("f_unmount result: %i\r\n", fStatus);

}

SDIO_DeInit();

}

while (1)
{
}
}


Вывод платы без отладчика:
CODE
Test FATFS Lib for STM32F217

f_mount result: 0

Test read file.
f_open result: 0
f_size result: 14
f_read result: fStatus: 0; uiStatus: 14;
Read data: Hello world!

f_close result: 0

Test write file.
f_open result: 0
f_size result: 0
f_write result: fStatus: 1; uiStatus: 0;
f_eof result: 1.
f_ulink result: 1
f_size result: 0
f_unmount result: 0


С отладчиком:
CODE
Test FATFS Lib for STM32F217
f_mount result: 0

Test read file.
f_open result: 0
f_size result: 14
f_read result: fStatus: 0; uiStatus: 14;
Read data: Hello world!

f_close result: 0

Test write file.
f_open result: 0
f_size result: 0
f_write result: fStatus: 0; uiStatus: 15;
f_eof result: 1.
f_size result: 15
f_unmount result: 0


Пошерстив сей прекрасный форум и поняв, что дурак я, немного полазив отладчиком подправила disk_write и disk_read.
CODE
/*-----------------------------------------------------------------------*/
/* Read Sector(s) */
DRESULT disk_read (
BYTE drv, /* Physical drive nmuber (0..) */
BYTE *buff, /* Data buffer to store read data */
DWORD sector, /* Sector address (LBA) */
BYTE count /* Number of sectors to read (1..255) */
)
{
/* ................................................................................
...............................*/
for (int secNum = 0; (secNum < count) && (Status == SD_OK); secNum++)
{
Status = SD_ReadBlock((buff+SECTOR_SIZE*secNum),
(sector+secNum)*SECTOR_SIZE,
SECTOR_SIZE);

while(SD_GetStatus() != SD_TRANSFER_OK);
}
/* ................................................................................
...............................*/
}



/*-----------------------------------------------------------------------*/
/* Write Sector(s) */

#if _READONLY == 0
DRESULT disk_write (
BYTE drv, /* Physical drive nmuber (0..) */
const BYTE *buff, /* Data to be written */
DWORD sector, /* Sector address (LBA) */
BYTE count /* Number of sectors to write (1..255) */
)
{
/* ................................................................................
...............................*/
for (int secNum = 0; (secNum < count) && (Status == SD_OK); secNum++)
{
Status = SD_WriteBlock((uint8_t *) buff+SECTOR_SIZE*secNum,
(sector+secNum)*SECTOR_SIZE,
SECTOR_SIZE);
while(SD_GetStatus() != SD_TRANSFER_OK);
}
/* ................................................................................
...............................*/
}
Ivan Kuznetzov
ну и зря переделали родной драйвер! у меня с этим diskio.c mp3 плеер заработал! (stdperiph 3.5.0)
ReRayne
Ivan Kuznetzov, почему, собственно, зря, если у меня в режиме пула не работало?)
IgorKossak, спасибо, что подправили пост, впредь, буду внимательней.
Ivan Kuznetzov
Цитата(ReRayne @ Jan 18 2012, 01:11) *
Ivan Kuznetzov, почему, собственно, зря, если у меня в режиме пула не работало?)

использую stdperiph driver v 3.5.0 и драйвера из папки STM32_EVAL. дак вот с последними дровами заработал только ваш diskio.c

у Вас запись после модификации работает?
ReRayne
Ivan Kuznetzov, в режиме пула работает.
В режиме DMA наблюдается отваливание SD карты после нескольких тысяч чтений, после перезагрузки снова все работает. Но эта проблема может быть вызвана не FATFS, а тем что она работает под FreeRTOS, так еще и LwIP крутится.
+ у меня еще изменен дефайн, т.к. частота 100Mhz вместо 120Mhz по-дефолту:
#define SDIO_TRANSFER_CLK_DIV ((uint8_t)0x00)

На:
#define SDIO_TRANSFER_CLK_DIV ((uint8_t)0x06)
inventor
Цитата(ReRayne @ Jan 18 2012, 12:09) *
Ivan Kuznetzov, в режиме пула работает.
В режиме DMA наблюдается отваливание SD карты после нескольких тысяч чтений, после перезагрузки снова все работает. Но эта проблема может быть вызвана не FATFS, а тем что она работает под FreeRTOS, так еще и LwIP крутится.
+ у меня еще изменен дефайн, т.к. частота 100Mhz вместо 120Mhz по-дефолту:
#define SDIO_TRANSFER_CLK_DIV ((uint8_t)0x00)

На:
#define SDIO_TRANSFER_CLK_DIV ((uint8_t)0x06)


я сделал эту фат с атмеловской платой, только вместо SPI использовал полный 4-х битный режим.
Все идеально работает, правда я не пробовал делать 1000 чтений и записей на SD карту.
ReRayne
inventor, на самом деле у меня большие подозрения на сам FATFS. Чтение падает с FR_NO_PATH. При том это лечится периодическим вызовом f_mount(DISK_LOGIC_NUMBER, NULL)(unmount т.е.). Работы с железом в этой функции нет.
А вы попробуйте сделать бесконечный цикл на чтение файла из файла, мне очень интересно, отвалится ли она у вас так же как у меня или нет sm.gif
batisto4ka
Цитата(ReRayne @ Jan 19 2012, 14:47) *
inventor, на самом деле у меня большие подозрения на сам FATFS. Чтение падает с FR_NO_PATH. При том это лечится периодическим вызовом f_mount(DISK_LOGIC_NUMBER, NULL)(unmount т.е.). Работы с железом в этой функции нет.
А вы попробуйте сделать бесконечный цикл на чтение файла из файла, мне очень интересно, отвалится ли она у вас так же как у меня или нет sm.gif


Подскажите по ветке http://electronix.ru/forum/index.php?showtopic=104591
Для просмотра полной версии этой страницы, пожалуйста, пройдите по ссылке.
Invision Power Board © 2001-2025 Invision Power Services, Inc.