Помощь - Поиск - Пользователи - Календарь
Полная версия этой страницы: Кто использовал SPI в slave mode AT91SAM7S?
Форум разработчиков электроники ELECTRONIX.ru > Микроконтроллеры (MCs) > ARM
vladimir_m
Инициализация:
Код
    AT91F_PMC_EnablePeriphClock ( AT91C_BASE_PMC, 1 << AT91C_ID_SPI );
            AT91F_SPI_Disable(AT91C_BASE_SPI);
            AT91F_SPI_Reset(AT91C_BASE_SPI);
    AT91F_SPI_CfgMode(AT91C_BASE_SPI,  AT91C_SPI_PS_FIXED |  AT91C_SPI_MODFDIS);
    AT91F_SPI_CfgCs(AT91C_BASE_SPI,
                    0,
                    AT91C_SPI_BITS_16 |
                    ((50 <<  8) & AT91C_SPI_SCBR) //Serial Clock Baud Rate ?????
                     );

    AT91F_AIC_ConfigureIt (AT91C_BASE_AIC, AT91C_ID_SPI, SPI_INTERRUPT_LEVEL,  AT91C_AIC_SRCTYPE_INT_POSITIVE_EDGE, spi_irq_handler);
    AT91F_SPI_EnableIt (AT91C_BASE_SPI,  AT91C_SPI_RDRF);
    AT91F_AIC_EnableIt (AT91C_BASE_AIC, AT91C_ID_SPI);
    AT91F_SPI_Enable(AT91C_BASE_SPI);

Прерывание:
Код
void spi_irq_handler(){
  unsigned int status = AT91C_BASE_SPI->SPI_SR;
  if (status & AT91C_SPI_RDRF)
  {
    debug_cnt++;
    ssc_buf_in[0] = ssc_buf_in[1];
    ssc_buf_in[1] = ssc_buf_in[2];
    ssc_buf_in[2] = AT91C_BASE_SPI->SPI_RDR;

  }
}

Передается последовательно 0xAA55, 0xAA56, 0xAA57. Смотрел осциллографом - все четко.
Принимается каша. При каждом запуске - разное. Причем такое впечатление, что начинает
вдвигаться в регистр SPI слово не с первого байта, а со случайного. В результате в приемном буфере
может оказаться, например 12 последних бит первого слова и 4 бита второго.
Передача идет на частоте 100КГц. Режимы передатчика и приемника совпадают.
Иногда, очень редко, все работает правильно.
В чем могут быть грабли?
gormih
Передатчик и приемник включаются/инициализируются одновременно?
mstr
GPIO для SPI-slave настроены нормально?
vladimir_m
Цитата(mstr @ Sep 22 2008, 11:32) *
GPIO для SPI-slave настроены нормально?

Два раза проверял - нормально...

Цитата(gormih @ Sep 21 2008, 11:41) *
Передатчик и приемник включаются/инициализируются одновременно?

В общем-то я не придавал этому значения. Передатчик и приемник рассинхронизированы.
По идее для SPI - это не проблема, т.к. первод NSS в неактивное состояние должден сбрасывать всякие счетчики в SPI.
Но в конце концов я решил это проверить. Сделал так. При старте настраиваю ножку NSS на вход общего назначения и дожидаюсь неактивного состояния сигнала, после чего присваиваю ей аппаратную функцию:
Код
  while (NSS);
  while (NSS == 0);
  AT91F_PIO_CfgPeriph(AT91C_BASE_PIOA, ( NSS_mask ), ( 0));

Здесь NSS и NSS_mask - макросы.
После этого запускаю SPI
Код
  AT91F_SPI_Enable(AT91C_BASE_SPI);

Вроде бы так работает. Что-то в errate я про это не читал...
gormih
Цитата(vladimir_m @ Sep 22 2008, 16:17) *
Вроде бы так работает. Что-то в errate я про это не читал...


errdate здесь не при чем. Дело в том, что на старте до окончания сброса ноги микроконтроллера могут находиться в произвольном состоянии. Соответственно, эти состояния воспринимаются приемникам как некие сигналы.
vladimir_m
И что? Допустим первый раз, два, три будут ошибочные чтения. Но потом должно все устаканится. NSS в "1" - и SPI в исходное состояние. Но этого же нет!?
_dem
Вот делюсь кодом, как есть - потратил на него недели две, наверное.
Будут вопросы - пишите.

Выдернуто из живого проекта, так что вряд ли соберется, но грабли с Slave mode на SAM7S там обойдены.

ps. Там все на PDC буферах.
vladimir_m
Цитата
Вот делюсь кодом, как есть - потратил на него недели две, наверное.

Спасибо.
Буду внимательно изучать. Правда времени на борьбу со spi больше у меня не было, поэтому исправил алгоритм работы и использую SAM в master mode. Повезло, что я его связываю с другим процем, там хоть глюков нет.
В любом случае, спасибо.
_dem
Пожалуйста. Кстати, master mode там тоже с приколами, поэтому тестируйте внимательно. В аттаче реализовано оба режима, будут вопросы - feel free smile.gif
Для просмотра полной версии этой страницы, пожалуйста, пройдите по ссылке.
Invision Power Board © 2001-2025 Invision Power Services, Inc.