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

Сегодня забил на все и засел за изучение STM32.
Платформа — 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

Комментарии (8)

RSS свернуть / развернуть
GPIO_PinRemapConfig(GPIO_Remap_SWJ_JTAGDisable, ENABLE); перед вызовом SD_Init();
Включить отключение — это сильно…

Вступить в блог вначале. В справочной (ссылка сверху) написано.
0
  • avatar
  • ACE
  • 07 сентября 2011, 19:25
Спасибо! Получилось перенести.
0
Может я неправильно понял, но в архиве лежит проект какой-то мигалки.
0
Автор, просим помощи! В архиве демо-проект для платы, просто мигалка! Пожалуйста, выложите исходник проекта, который касается данной статьи. Мне очень интересно посмотреть реализацию работы с картой памяти на STM32.
0
> Мне очень интересно посмотреть реализацию работы с картой памяти на 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. Тоже работает нормально. Только там дольше продираться через определения типа платы.
0
Большое спасибо! А то, видимо, я где-то ошибаюсь и никак моя MMC-карточка не хочет отвечать. Будем разбираться.
0
Привет)) а вот по поводу ремапа SPI1:
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;

Но спорить не буду: на вкус и цвет все фломастеры разные))
0
Кстати, автору спасибо — очень помогла статья)))
0
Только зарегистрированные и авторизованные пользователи могут оставлять комментарии.