В этом примере я использовал отладочную плату Olimex SAM7-EX256 с микроконтроллером AT91SAM7X256. Карточка SD была на 512 мегабайт (хотя подходят и другие карточки MMC и SD). Использовался пример usb-device-massstorage-project от IAR и модули из библиотеки EFSL (для работы с карточкой SD/MMC по последовательному интерфейсу SPI), см. ссылки [2].
1. Берем за основу проект usb-device-massstorage-project из примеров IAR (находится в папке $TOOLKIT_DIR$\examples\Atmel\at91sam7x-ek\usb-device-massstorage-project\, или c:\Program Files\IAR Systems\Embedded Workbench 5.0 Evaluation\ARM\examples\Atmel\at91sam7x-ek\usb-device-massstorage-project\), копируем его в отдельную папку, добиваемся нормальной компиляции (правкой соответствующих опций и файлов, см. [6]). Предположим, это будет папка c:\asm\MSD-MMC\. Компилировать надо для конфигурации проекта at91sam7x256_sram (поскольку в качестве памяти у нас пока выступает flash микроконтроллера). Проверяем, что наше устройство USB Mass Storage Device (далее просто MSD) работает - пробуем его отформатировать, читать и писать (MSD должно получиться размером 34 килобайта).
2. Теперь займемся подключением карточки SD. К картам SD/MMC можно обращаться через последовательный интерфейс, который реализован в карточке. В микроконтроллере этому интерфейсу соответствует SPI (в моем примере используется SPI0). Карточка запитывается от напряжения 3.3 вольт. При подключении к микроконтроллеру карточка работает под управлением микроконтроллера, т. е. в терминах SPI карточка является slave, а микроконтроллер - master. Используются следующие сигналы и питание:
1. CD - выход микроконтроллера, выборка карточки, активный сигнал 0. В моем примере это ножка 21 AT91SAM7X256, порт PA13, аппаратная выборка slave-устройства SPI0_NPSC1.
2. CMD - выход микроконтроллера, сигнал данных, поступающих в карточку. Подключен к ножке 25 AT91SAM7X256, порт PA17, сигнал MOSI интерфейса SPI0.
3. GND
4. +3.3V
5. CLK - выход микроконтроллера, тактовый сигнал, поступающий на карточку. Подключен к ножке 26 AT91SAM7X256, порт PA18, сигнал SPCK интерфейса SPI0.
6. GND
7. DAT0 - вход микроконтроллера, поток данных, поступающий от карточки. Подключен к ножке 24 AT91SAM7X256, порт PA16, сигнал MISO интерфейса SPI0.
8. Не используется, подключен нагрузочный pullup-резистор 100 к на +3.3V.
9. Не используется, подключен нагрузочный pullup-резистор 100 к на +3.3V.
На плате Olimex все уже подключено, остается только запрограммировать микроконтроллер.
 |
 |
№
конт.
|
сигнал
|
описание
|
Вариант подключения
к SPI0, PIOA, периферия A
|
1
|
~CS
|
выборка карты (режим DAT3 не используется)
|
PA13
|
2
|
MOSI
|
данные, приходящие на вход карты
|
PA17
|
3
|
GND
|
минус питания карты, сигнальная земля
|
|
4
|
VCC
|
плюс питания карты, от 2.7 до 3.6 вольт, самый лучший вариант 3 вольта
|
|
5
|
SCK
|
такты данных, поступающие на вход карты
|
PA18
|
6
|
GND
|
минус питания карты, сигнальная земля |
|
7
|
MISO
|
данные, уходящие с выхода карты (DAT0)
|
PA16
|
8
|
|
не используется (DAT1)
|
|
9
|
|
не используется (DAT2)
|
|
3. Добавляем программную поддержку работы с карточкой.
- добавляем в проект файлы MEDmmc.c и MEDmmc.h. Их надо записать в папку at91lib\memories, и файл MEDmmc.c добавить в группу проекта at91lib\memories.
- добавляем в корень папки проекта папку efsl с её файлами, и настраиваем в опциях проекта пути до неё.
- делаем в проекте группу efsl и туда помещаем файлы efsl\sd.c и efsl\at91_spi.c.
4. В опциях проекта удалаем макроопределение sram и добавляем макроопределения at91sam7x256 (если его нет), MMC_MEDIA, OlimexDBG и NOTRACE (Project -> Options... -> C/C++ Compiler -> Preprocessor -> Defined symbols: (one per line)). Макрос MMC_MEDIA понадобится, чтобы включить поддержку SD/MMC. Макрос OlimexDBG нужен, чтобы мигал индикационный светодиодик, который можно подключить к ножке 66 AT91SAM7X256 (порт PB21). Макрос NOTRACE нужен, чтобы отключить вывод в DBGU сообщений протокола USB, иначе наше MSD будет работать очень медленно.
5. Включаем поддержку пользовательского сброса. Этот шаг необязателен - если его не сделать, то вызов RSTC_SetUserResetEnable делать не надо. Добавляем в проект группу at91lib\peripherials\rstc и туда помещаем файл rstc.c.
6. Добавляем/правим в main:
#include <rstc/rstc.h>
#include <memories/MEDmmc.h>
...
//Порт PB21, ножка 66 - используется для
// тестирования программ как выход.
#define PIN_PB21_TEST66 {1 << 21,
AT91C_BASE_PIOB,
AT91C_ID_PIOB,
PIO_OUTPUT_0,
PIO_DEFAULT}
const Pin outPB21_66 = PIN_PB21_TEST66;
void LED (unsigned char on)
{
on ? PIO_Set(&outPB21_66) : PIO_Clear(&outPB21_66);
}
volatile AT91PS_RSTC pRSTC = AT91C_BASE_RSTC;
...
int main()
{
//разрешаем сброс от кнопки (если это Вам нужно)
RSTC_SetUserResetEnable(pRSTC, 1);
//запускаем вывод отладочных сообщений через DBGU
#ifdef NOTRACE
const Pin pinsDbgu[] = {PINS_DBGU};
PIO_Configure(pinsDbgu, PIO_LISTSIZE(pinsDbgu));
DBGU_Configure(DBGU_STANDARD, 115200, BOARD_MCK);
#else
trace_CONFIGURE(DBGU_STANDARD, 115200, BOARD_MCK);
#endif
printf("-- USB Device Mass Storage Project 1.4 --\n\r");
// If they are present, configure Vbus & Wake-up pins
PIO_InitializeInterrupts(0);
//тестовая ножка, управляющая светодиодом LED
PIO_Configure(&outPB21_66, 1);
WAKEUP_CONFIGURE();
...
// Flash (only when NOT running in flash)
#if defined(AT91C_BASE_EFC) && !defined(flash) && defined(FLASH_MEDIA)
trace_LOG(trace_INFO, "LUN Flash\n\r");
if (numMedias == 0)
{
FLA_Initialize(&(medias[numMedias]),
AT91C_BASE_EFC);
LUN_Init(&(luns[numMedias]),
&(medias[numMedias]),
buffer,
30*1024, 34*1024, BLOCK_SIZE);
numMedias++;
// Install handler for flash interrupt
AIC_ConfigureIT(AT91C_ID_SYS,
AT91C_AIC_PRIOR_LOWEST,
ISR_Media);
AIC_EnableIT(AT91C_ID_SYS);
}
#endif
#if defined(MMC_MEDIA)
trace_LOG(trace_INFO, "LUN mmc\n\r");
if (numMedias == 0)
{
MMC_Initialize(&(medias[numMedias]),
AT91C_BASE_SPI0);
LUN_Init(&(luns[numMedias]),
&(medias[numMedias]),
buffer,
0, medias[numMedias].size, BLOCK_SIZE);
numMedias++;
}
#endif
ASSERT(numMedias > 0, "Error: No media defined.\n\r");
...
}
Это все! Теперь у Вас доступно USB Mass Storage Device на карточках SD/MMC, которое работает как обычная флешка. Правда, скорость у неё в разы меньше. Я пробовал разные карточки - MMC на 16 мегабайт и SD на 512 мегабайт, и получил скорость чтения 336 кбайт/сек, а скорость записи 180 кбайт/сек. Протокол приема-передачи на карточку через SPI сильно грузит AT91SAM7X256, поэтому для увеличения скорости желательно убрать все фоновые задачи из главного цикла main, а также все ненужные прерывания.
[Ссылки]
1. Готовый проект MSD-MMC можно скачать здесь.
2. Сайт EFSL.
3. IAR EW ARM: работа с файловой системой FAT на карточках SD/MMC.
4. Библиотека EFSL.
5. Другая популярная реализации файловой системы для микроконтроллеров - Petit FAT File System Module. См. также FatFs Generic FAT File System Module, как использовать SD/MMC.
6. IAR EW ARM: как перенести проект в другую папку.
|
Комментарии
2012-11-0113:51:14 syper