Jump to content

    

[MEGA8] Проблема с SPI slave

Доброго времени суток, возникла необходимость допилить уже существующий девайс на восьмой меге, добавив туда измерение времени с выдачей результата мастеру на ADUC836.

Проблема в том, что постоянно возникают коллизии при записи ответа в SPDR, пробовал добавлять на мастере задержки между отправляемыми байтами - безрезультатно.

 

Кусок кода мастера (с51) выглядит так:

 

set_spi_ss(1);
   delay_ms(1);

   // signature
   cs = 'F';
   EA = 0;
   SPIDAT = cs;
   while(ISPI == 0);
   ISPI = 0;
   b = SPIDAT;
   EA=1;
   spi_test[0] = b;
   //mode
   cs += 5;
   EA=0;
   SPIDAT = 5;
   while(ISPI == 0);
   ISPI = 0;
   b = SPIDAT;
   EA = 1;
   spi_test[0] = b;

   ... (тут остальные байты пакета данных)

  set_spi_ss(0);
   delay_ms(1);

 

Код мастера отлажен и работает с данным девайсом (только на передачу), ЦАПом, флешкой. Полярность/фаза у обоих естественно те же самые.

 

Код slave'a (avrgcc) покамест вообще обрезал до безобразия, убрав запись в буфер/проверку SPCR на коллизии, оставив только "голый" ответ:

 

void SPI_SlaveInit(void)
{
DDRB=(1<<PINB4) | (BIT(0)) | (BIT(1));           //MISO as OUTPUT
SPCR=(1<<SPE)|(1<<SPIE);       //Enable SPI && interrupt enable bit
SPDR=0x88;
} 

ISR (SPI_STC_vect)
{
UCHAR c = SPDR;
 SPDR = 0x55; // that's what i'm trying to send back
}

 

 

В свое время делал подобный обмен по SPI на 8051-совместимых и STM32, подобных проблем не вылезало :(.

Буду премного благодарен за любой пинок в нужном направлении.

Share this post


Link to post
Share on other sites

А почему в мастере дожидаетесь передачи не после всех выводов в SPIDAT?

Share this post


Link to post
Share on other sites
А почему в мастере дожидаетесь передачи не после всех выводов в SPIDAT?

 

В передаче-приеме каждого байта есть ожидание конца передачи вида "SPIDAT = ХХХ; while(ISPI == 0);"

Share this post


Link to post
Share on other sites

Полярность сигнала SS "наоборот". Проверьте его.

Share this post


Link to post
Share on other sites
Полярность сигнала SS "наоборот". Проверьте его.

 

Полагаю, вас могли ввести в заблуждение аргументы функции set_spi_ss(), но с ними, увы, все хорошо. Это индекс слейвселекта для вывода на МС дешифратора; сейчас их используется 3 штуки.

 

void set_spi_ss(unsigned char ss)
{
   SPI_SS1 = ss & 0x01;
   SPI_SS2 = (ss & 0x02) >> 1;
}

Share this post


Link to post
Share on other sites

Частота SPI не должна превышать четверть частоты меги.

Share this post


Link to post
Share on other sites

Проверьте соответствие кол-во байт в запросе мастера, и ожидаемое им (мастером) кол-во байт ответа от слейва.

Кроме того, не понял какие могут быть коллизии (не спец по Atmaga) - ведь если речь о шине - то их там не может быть в принципе

(если не мультимастер).

ps

ISR (SPI_STC_vect) - не знаю принцип организации обработки прерываний в Atmega, но

как определяется причина "влета" в вектор ? Что является источником возникновения прерывания.

(пустой регистр передачи, пустой буферный регистр, принятый байт итд ) ?

 

Edited by k155la3

Share this post


Link to post
Share on other sites

В меге SPI interrupt у слейва возникает после приема очередного байта от мастера. Коллизии возникают вида "запись в регистр во время активной передачи данных".

Частота SPI у ADUC'a самая медленная, Fclk/16.

 

Жаль что до понедельника напрочь отсутствует осциллограф, а вместе с ним и возможность взглянуть поподробнее на творящееся безобразие :(

Share this post


Link to post
Share on other sites

Попробуйте поменять чип. У меня был случай в готовом у-ве (с мега 644) в режим мастера, когда после перехода MISO в ноль стирался произвольный блок FLASH. После замены все нормально заработало. Наверно было короткое замыкание в кристалле. Правда, это маловероятно, но кто знает.

Share this post


Link to post
Share on other sites
(1) В меге SPI interrupt у слейва возникает после приема очередного байта от мастера. Коллизии возникают вида "запись в регистр во время активной передачи данных".

. . . .

(2)Жаль что до понедельника напрочь отсутствует осциллограф, а вместе с ним и возможность взглянуть поподробнее на творящееся безобразие :(

(1) я так понял буферизации нет.

(2) сильно облегчите себе жизнь исползуя лог. анализатор, который позволяет "разобрать" протокол. Посмотрите 2-3 месяца назад была тема по

разбору "полетов" на I2C тут (лог. анализатор) Saleae.

Цена вопроса 15 кваксов - если готовое.

Share this post


Link to post
Share on other sites

@ivn ->Чип менять пробовал (есть 2 идентичные платы)

 

@k155la3 -> 1) буферизация есть, во всяком случае если верить даташиту:

 

The system is single buffered in the transmit direction and double buffered in the receive direction.

This means that bytes to be transmitted cannot be written to the SPI Data Register before

the entire shift cycle is completed. When receiving data, however, a received character must be

read from the SPI Data Register before the next character has been completely shifted in. Otherwise,

the first byte is lost.

 

Другой вопрос что если верить тому же даташиту, можно пихать данные в SPDR даже перед чтением очередного пришедшего байта, на практике этого как-то не видно.

 

(2) До прихода 2 недели назад некоего студиозуса для прохождения практики ассортимент всякой измерительно-аналитической техники был побольше. К сожалению сей талантливый индивид за неделю каким-то образом ухайдохал осциллограф цифровой обычный - одна штука, старенький осциллограф-примочка к РС Disco - одна штука и мультиметр - одна штука. Судя по выгоревшему в последнем предохранителю, не обошлось без ~220v.

Share this post


Link to post
Share on other sites

Вам бы почитать как Mega работает как слейв и Вы бы сразу нашли ошибку

Share this post


Link to post
Share on other sites
Другой вопрос что если верить тому же даташиту, можно пихать данные в SPDR даже перед чтением очередного пришедшего байта, на практике этого как-то не видно.

Вообще-то из даташита это не следует: даташит не утверждает про независимость буфера для передачи и буфера-защелки приемника.

Если в прерывании слейв ничего не будет записывать в SPDR, то мастер при каждом последующем обмене будет получать свой предыдущий байт.

Что как бы намекает, что буфер для передачи и второй приемный буфер - один и тот же регистр.

Share this post


Link to post
Share on other sites

По моему мнению, если с железом все ОК, то ошибка может быть только в отсутствии или недостаточной задержки между байтами при передачи Мастера

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
Sign in to follow this