На тракторе через засады. (STM32[SPI]->SD)

Платформа — STM32VL-Discovery, припаял к ней переходник USART-USB от телефона на PL-2303 и переходник SD-MicroSD, используемый как разъем для SD-карты. В итоге хочу получить регистратор температуры 6-канальный на датчиках KTY83-111 с записью на SD-карту и RTC. Пусть сначала пишет все в текстовом виде.
Подключил я SD к линиям PB3-PB5 и PA15, но об этом далее.
Подготовился. Скачал IAR 6.20, прочитал статью про STM8+IAR+стандартные библиотеки (спасибо автору!), решил начать с компиляции примера в an3268.
Опа. Засада №1. При компиляции вылетает множество ошибок типа
Error[Pe147]: declaration is incompatible with "__interwork __softfp unsigned long __RBIT(unsigned long)" (declared at line 174 of "C:\Program Files\IAR Systems\Embedded Workbench 6.0 Kickstart\arm\inc\c\intrinsics.h") F:\EL\!!MCU\stm32vldiscovery_package\an3268\stm32vldiscovery_package\Libraries\CMSIS\CM3\CoreSupport\core_cm3.h 1134
Видно, что хедер intrinsics.h конфликтует с core_cm3.h А ведь недавно этот пример хорошо компилировался (правда, на IAR 6.10). Да и под IAR 6.20 пример для STM32L-Discovery работал замечательно (я даже на встроенный термометр посмотрел, и шумы АЦП померял).
Разобрался. Оказывается, изменился CMSIS. На эту проблему есть комментарий:
supp.iar.com/Support/?note=75890&from=search+result
supp.iar.com/FilesPublic/UPDINFO/005832/arm/doc/infocenter/iccarm.ENU.html
Исправил. Вкратце, надо спрятать core_cm3.h (убрать папку, где он лежит из поиска include в опциях препроцессора для C/С++), и в опциях же включить для проекта встроенный CMSIS.
Далее. Создал шаблон проекта с библиотеками. Подключаю мешанину из (хедеров, исходников, примеров) для работы с SD по SPI (SDIO пока не трогаю). Еле добился, чтобы компилировалось. Запускаю. Конечно, сомневался, что все сразу заработает, но а вдруг…
Конечно, не заработало. Надо было исправить конфигурацию — SD подключено к SPI1, всякое GPIOA, GPIOB, RCC, SPI1… Пробую. Все равно не работает. Стал разбираться при помощи провода с крокодильчиком, резистором и светодиодиком. Цепляю к PA15, отлаживаю пошагово. На команду SD_CS_HIGH(); не реагирует. Все проверил, на кучу раз. Написал отдельно кусок кода, который должен тестировать. 1-в-1 как для светодиода. Но светодиод работает, а CS для SD — нет.
Заподозрил неладное, полез в даташит. Вижу:
Засада №2. На ножке PA15 висит JTDI. JTDI — это JTAG. Скорее всего, после Reset он включен. Так и оказалось. (кстати, я уже нарывался на ту же самую засаду в ATMEGA32). Ладно. Ищу как отключить. Отключаю командой
GPIO_PinRemapConfig(GPIO_Remap_SWJ_JTAGDisable, ENABLE); перед вызовом SD_Init();
Ладно. Линия PA15 работает, в чем убедился при помощи светодиода:
GPIO_InitTypeDef GPIO_InitStructure;
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_15;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
GPIO_Init(GPIOA, &GPIO_InitStructure);
GPIO_SetBits(GPIOA, GPIO_Pin_15);
GPIO_ResetBits(GPIOA, GPIO_Pin_15);
GPIO_SetBits(GPIOA, GPIO_Pin_15);
GPIO_ResetBits(GPIOA, GPIO_Pin_15);
GPIO_SetBits(GPIOA, GPIO_Pin_15);
Иду далее. Все равно не работает чтение с SD. Стал тестировать PB3, PB4, PB5 (на вывод, аналогичным кодом). PB5 работает, PB3,4 — нет. Снова иду в даташит — и точно! PB3, PB4 — это 2 другие линии JTAG! Тестирование линий надо проводить после выражения GPIO_PinRemapConfig(GPIO_Remap_SWJ_JTAGDisable, ENABLE);
Ну, тут, признаю, можно было сразу догадаться. Пол-засады №3. Еще пол-засады — не подал клок перед тестированием командой RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE);
Все. Линии тестируются. SPI не работает. Смотрю в примеры. Вижу, что SPI1 — совершенно на других ножках у всех висит. Иду в референс-мануал. И нахожу раздел: SPI1 alternate function remapping

Это — засада №4. На самом деле, удобная вещь (в STM32L1xx она получила дальнейшее развитие). У SPI1 есть 2 конфигурации. В одной он подключен к ножкам PA15,PB3-5, в другой — PA4-PA7. Последняя — основная. PA15,PB3-5 включается установкой бита в соответствующем регистре альтернативных конфигураций:
AFIO_MAPR |= AFIO_MAPR_SPI1_REMAP;
Как это сделать при помощи библиотеки — не нашел.
Казалось бы, все просто. Находим, в каком заголовке определяются AFIO_MAPR_SPI1_REMAP и AFIO_MAPR, подключаем его — и вуаля! Для поиска, где что находится, удобно использовать «Go to definition of...» (ПКМ на интересующей конструкции в коде), или Alt-F7 в FAR, предварительно зайдя в место, где лежат исходники.
Оказалось, «не вуаля».
Засада №5
Подключаем хедер директивой #include <ST/iostm32f100xB.h>
При компиляции видим кучу ошибок. Оказывается, данный хедер конфликтует с stm32F10x.h по слову BKP. В последнем он означает периферию-backup-регистры.
Решил вопрос, вытащив из ST/iostm32f100xB.h лишь одну интересующую конструкцию с вспомогательными определениями.
#define __IO_REG32_BIT(NAME, ADDRESS, ATTRIBUTE, BIT_STRUCT)\
volatile __no_init ATTRIBUTE union \
{ \
unsigned long NAME; \
BIT_STRUCT NAME ## _bit; \
} @ ADDRESS
#define __REG32 unsigned long
typedef struct {
__REG32 SPI1_REMAP : 1;
__REG32 I2C1_REMAP : 1;
__REG32 USART1_REMAP : 1;
__REG32 USART2_REMAP : 1;
__REG32 USART3_REMAP : 2;
__REG32 TIM1_REMAP : 2;
__REG32 TIM2_REMAP : 2;
__REG32 TIM3_REMAP : 2;
__REG32 TIM4_REMAP : 1;
__REG32 : 2;
__REG32 PD01_REMAP : 1;
__REG32 : 8;
__REG32 SWJ_CFG : 3;
__REG32 : 5;
} __afio_mapr_bits;
__IO_REG32_BIT(AFIO_MAPR, 0x40010004, ,__afio_mapr_bits);
Как сделать правильно — не знаю.
В общем, в итоге заработало, и я увидел первый сектор моей SD-карточки. Буду прикручивать FAT.

В процессе работы пробовал переключиться на симулятор, как средство отладки. Надеялся, что можно будет посмотреть настройки периферии, как в AVR-studio и VisualDeveloper для STM8, однако еще одна засада(№6)… в IAR такого не нашел. Переключаюсь обратно на ST-Link, вижу засаду №7. Все компилируется, но на этапе заливки выдает warning'и. Означают они, что при проверке в контроллере оказалось не то, что записывали. Ну, думаю, все. Вместе с JTAG отключил SWD. Однако, отладка шла, можно было останавливать и выполнять пошагово. Предположил, что просто слетела настройка проекта с адресами для прошивки флеша. Перезагрузил все — не помогло. Пригодился шаблон проекта. Пересоздал, скопировал туда измененные исходники — все заработало.
В общем, умудрился я с 1 раза попасть в JTAG, да еще и редирекченный SPI… :-)
Конечно, можно быть внимательнее, и заранее читать даташиты — но на то это и засады.
Почему на тракторе? — медленно, но верно.
Получилось несколько сумбурно, но я весь день был в отладке :-)
шаблон тоже выкладываю. Мои разработки лежат в F:\my\; там же в папке !SPL лежат библиотеки. На это рассчитан шаблон. Возможно, надо будет по-новой добавить файлы, на которые IAR ругнется при входе в .eww.
- 0
- 07 сентября 2011, 17:48
- DrAG0n
- 1
Файлы в топике:
drg-iar-template.zip
Автор, просим помощи! В архиве демо-проект для платы, просто мигалка! Пожалуйста, выложите исходник проекта, который касается данной статьи. Мне очень интересно посмотреть реализацию работы с картой памяти на STM32.
> Мне очень интересно посмотреть реализацию работы с картой памяти на STM32.
Здесь www.siwawi.arubi.uni-kl.de/avr_projects/arm_projects/arm_memcards/index.html#chanfat_stm32 готовый проект общения с картой по SPI с прикрученной FAT от Чана. Свежую версию FAT берем отсюда elm-chan.org/fsw/ff/00index_e.html. Проверено — работает.
Можно взять общение с картой из ИАРовских примеров. Лежит в папке ИАР \arm\examples\ST\STM32F10x\IAR-STM32F103ZE-SK\MassStorage. Тоже работает нормально. Только там дольше продираться через определения типа платы.
Здесь www.siwawi.arubi.uni-kl.de/avr_projects/arm_projects/arm_memcards/index.html#chanfat_stm32 готовый проект общения с картой по SPI с прикрученной FAT от Чана. Свежую версию FAT берем отсюда elm-chan.org/fsw/ff/00index_e.html. Проверено — работает.
Можно взять общение с картой из ИАРовских примеров. Лежит в папке ИАР \arm\examples\ST\STM32F10x\IAR-STM32F103ZE-SK\MassStorage. Тоже работает нормально. Только там дольше продираться через определения типа платы.
Привет)) а вот по поводу ремапа SPI1:
«Как это сделать при помощи библиотеки — не нашел.»
Поискал и нашел. Делается это так же как и отключение
Файл stm32f10x_gpio.c
Но мне как-то не по себе стало когда увидел реализацию этих функций. Поэтому проще написать так:
Но спорить не буду: на вкус и цвет все фломастеры разные))
AFIO_MAPR |= AFIO_MAPR_SPI1_REMAP;
«Как это сделать при помощи библиотеки — не нашел.»
Поискал и нашел. Делается это так же как и отключение
GPIO_Remap_SWJ_JTAGDisable
и через эту же функцию:GPIO_PinRemapConfig(GPIO_Remap_SPI1, ENABLE);
Файл stm32f10x_gpio.c
Но мне как-то не по себе стало когда увидел реализацию этих функций. Поэтому проще написать так:
AFIO->MAPR |= AFIO_MAPR_SPI1_REMAP;
AFIO->MAPR |= AFIO_MAPR_SWJ_CFG_JTAGDISABLE;
Но спорить не буду: на вкус и цвет все фломастеры разные))
Комментарии (8)
RSS свернуть / развернуть