реклама на сайте
подробности

 
 
> Проблема с SPI, зависает при обращении к SPDR
Alex Truhin
сообщение Oct 7 2010, 10:33
Сообщение #1





Группа: Новичок
Сообщений: 8
Регистрация: 13-04-10
Пользователь №: 56 609



Atmega 128 и память AT45DB321, читаю статус памяти,
SELECT();
status = DF_SPI_RW(StatusReg);
status = DF_SPI_RW(0x00);
DESELECT();

static uint8_t DF_SPI_RW( uint8_t tx )
{
uint8_t rx;
SPDR = tx;
while(!(SPSR & 0x80));
rx = SPDR;
return rx;
}
при первом чтении все ОК, но при повторном чтении, на строке status = DF_SPI_RW(0x00);
программа зависает, т.е. SPSR не взводиться.
Возможно есть проблемы с памятью, но почему не взводится флаг SPSR? Ведь насколько я понимаю,
мастер устройству пофиг на реакцию слэйв устройства на SPI?
Go to the top of the page
 
+Quote Post
2 страниц V   1 2 >  
Start new topic
Ответов (1 - 20)
aesok
сообщение Oct 7 2010, 10:53
Сообщение #2


Знающий
****

Группа: Участник
Сообщений: 596
Регистрация: 26-05-06
Из: Москва
Пользователь №: 17 484



Код настройки SPI.
Функция DF_SPI_RW - это первая функция вызываемая из main ()?

Анатолий.
Go to the top of the page
 
+Quote Post
Alex Truhin
сообщение Oct 7 2010, 15:17
Сообщение #3





Группа: Новичок
Сообщений: 8
Регистрация: 13-04-10
Пользователь №: 56 609



Код настройки:
static uint8_t df_GetStatus()
{
uint8_t status;

SELECT();
status = DF_SPI_RW(StatusReg);
status = DF_SPI_RW(0x00);
DESELECT();

return status;
}
....
SPCR = 0; // Отключаем SPI чтобы сконфигурировать направление ножек
DESELECT();
DDRB &= ~(DF_MISO_PB + DF_READY);
DDRB |= DF_MOSI_PB + DF_SCK_PB + DF_SS_PB; // + DF_RESET_PB /* MOSI, SS, RESET, SCK - выходы */
SPCR = (1<<SPE) | (1<<MSTR) | (1<<CPHA) | (1<<CPOL); // Enable SPI in Master mode, mode 3
SPSR = (1<<SPI2X);

Определяю тип памяти:
chip_id = df_GetStatus() & 0x3C;
Это нормально отрабатывает, а вот дальше через некоторое время вызов df_GetStatus(), виснет на строке while(!(SPSR & 0x80));,
причем у меня несколько устройств, практически одинаковых, на некоторых работает, на некоторых нет.
Сижу вторые сутки нет ни каких идей. Хотя бы в принципе, отчего может не устанавливаться SPSR? Либо в каких ситуациях он сбрасывается кроме записи в SPDR?
Go to the top of the page
 
+Quote Post
Lmx2315
сообщение Oct 7 2010, 17:55
Сообщение #4


отэц
*****

Группа: Свой
Сообщений: 1 729
Регистрация: 18-09-05
Из: Москва
Пользователь №: 8 684



прошу прощения если не на то ссылку даю и если ничем особо новым тут не блесну - вот тут описание SPI для atmega128

http://www.gaw.ru/html.cgi/txt/doc/micros/avr/arh128/15.htm
Цитата
void SPI_MasterInit(void)
{
/* Установка MOSI и SCK на вывод, все остальные на ввод */
DDR_SPI = (1<<DD_MOSI)|(1<<DD_SCK);
/* Разрешение SPI в режиме мастера, установка скорости связи fck/16
*/SPCR = (1<<SPE)|(1<<MSTR)|(1<<SPR0);
}
void SPI_MasterTransmit(char cData)
{
/* Запуск передачи данных */
SPDR = cData;
/* Ожидание завершения передачи данных */
while(!(SPSR & (1<<SPIF)))
;
}


--------------------
b4edbc0f854dda469460aa1aa a5ba2bd36cbe9d4bc8f92179f 8f3fec5d9da7f0
SHA-256
Go to the top of the page
 
+Quote Post
KSANDER
сообщение Oct 8 2010, 07:44
Сообщение #5





Группа: Участник
Сообщений: 14
Регистрация: 28-03-08
Пользователь №: 36 297



Цитата(Alex Truhin @ Oct 7 2010, 19:17) *
Сижу вторые сутки нет ни каких идей. Хотя бы в принципе, отчего может не устанавливаться SPSR? Либо в каких ситуациях он сбрасывается кроме записи в SPDR?


Эта ситуация не может возникнуть в Вашем случае?:

Alternatively, the SPIF bit is cleared by first reading the
SPI Status Register with SPIF set, then accessing the SPI Data Register (SPDR).
Go to the top of the page
 
+Quote Post
Alex Truhin
сообщение Oct 8 2010, 08:50
Сообщение #6





Группа: Новичок
Сообщений: 8
Регистрация: 13-04-10
Пользователь №: 56 609



Цитата(KSANDER @ Oct 8 2010, 17:44) *
Эта ситуация не может возникнуть в Вашем случае?:
Alternatively, the SPIF bit is cleared by first reading the
SPI Status Register with SPIF set, then accessing the SPI Data Register (SPDR).

Да вроде нет. Запись в SPDR и сразу простой цикл ожидания, компилируется он нормально:
while(!(SPSR & 0x80));
c7c: 77 9b sbis 0x0e, 7 ; 14
c7e: fe cf rjmp .-4 ; 0xc7c <_Z12df_FlashReadjjjPh+0x74>
так что вроде некому сбросить SPIF

Хм. Вот нашел аналогичную тему, и то же нет решения:
http://electronix.ru/forum/lofiversion/index.php/t59387.html
Go to the top of the page
 
+Quote Post
GDI
сообщение Oct 8 2010, 09:26
Сообщение #7


Профессионал
*****

Группа: Свой
Сообщений: 1 235
Регистрация: 14-05-05
Из: Санкт-Петербург
Пользователь №: 5 008



Ногу WP подтяните к питанию у АТ45. Можно просто соплю повесить, там нога питания соседняя, если корпус SO-8.


--------------------
http://www.embedders.org Блоги разработчиков электроники.
Go to the top of the page
 
+Quote Post
aesok
сообщение Oct 8 2010, 09:48
Сообщение #8


Знающий
****

Группа: Участник
Сообщений: 596
Регистрация: 26-05-06
Из: Москва
Пользователь №: 17 484



Как запрограмирован фьюз M103C?
Как скомпилировалась строка rx = SPDR;? Проверте везде не только в функции DF_SPI_RW, но и во всех местах где она проинлайнилась. не выкинул ли ее компилятор.
Есть ли в других местах программы обращение к регистру SPDR? Поставте в отладчике остановку по обращению к адресу SPDR, возможно в него кто то пишет по указателю.
Состояние бита WCOL в SPSR?

Анатолий.
Go to the top of the page
 
+Quote Post
777777
сообщение Oct 8 2010, 10:03
Сообщение #9


Профессионал
*****

Группа: Участник
Сообщений: 1 091
Регистрация: 25-07-07
Из: Саратов
Пользователь №: 29 357



А не сбрасывает ли кто SPE случайно? Может просто ноль в SPCR пишет?

Цитата(Alex Truhin @ Oct 7 2010, 14:33) *
static uint8_t DF_SPI_RW( uint8_t tx )
{
uint8_t rx;
SPDR = tx;
while(!(SPSR & 0x80));
rx = SPDR;
return rx;
}

Немного позанудствую: а так не проще?
uint8_t DF_SPI_RW( uint8_t tx )
{
SPDR = tx;
while(!(SPSR & (1<<SPIE))) {}
return SPDR;
}
Go to the top of the page
 
+Quote Post
Сергей Борщ
сообщение Oct 8 2010, 10:25
Сообщение #10


Гуру
******

Группа: Модераторы
Сообщений: 8 455
Регистрация: 15-05-06
Из: Рига, Латвия
Пользователь №: 17 095



Цитата(777777 @ Oct 8 2010, 13:03) *
А не сбрасывает ли кто SPE случайно?
Можно еще спросить - не настроена ли на ввод нога SS и не подается ли на нее низкий уровень?


--------------------
На любой вопрос даю любой ответ
"Write code that is guaranteed to work, not code that doesn’t seem to break" (C++ FAQ)
Go to the top of the page
 
+Quote Post
Alex Truhin
сообщение Oct 8 2010, 10:53
Сообщение #11





Группа: Новичок
Сообщений: 8
Регистрация: 13-04-10
Пользователь №: 56 609



Ну по порядку:
Цитата
GDI: Ногу WP подтяните к питанию у АТ45. Можно просто соплю повесить, там нога питания соседняя, если корпус SO-8.

WP напрямую на мониторе питания, так что тут проблем нет
Цитата
aesok: Как запрограмирован фьюз M103C?

Не запрограммирован, т.е. нормальный режим atmega 128
Цитата
Как скомпилировалась строка rx = SPDR;?

SPDR = tx;
876: 8f b9 out 0x0f, r24 ; 15
878: 80 e0 ldi r24, 0x00 ; 0
Цитата
Проверте везде не только в функции DF_SPI_RW, но и во всех местах где она проинлайнилась. не выкинул ли ее компилятор. Есть ли в других местах программы обращение к регистру SPDR?

В нерабочем/тестируемом куске именно такой код, т.е. не выкинул все ОК.
Цитата
Поставте в отладчике остановку по обращению к адресу SPDR, возможно в него кто то пишет по указателю.

Не распаян у меня JTAG, пока посмотреть не могу.
Цитата
Состояние бита WCOL в SPSR?

Посмотрю, может завтра (у нас уже вечер).
Цитата
777777: А не сбрасывает ли кто SPE случайно? Может просто ноль в SPCR пишет?

Нет. Сделал таймаут ожидания:
SPDR = tx;
uint8_t Cnt = 0;
while(((SPSR & 0x80) == 0) and (Cnt++ < 0xFE));
rx = SPDR;
Функция начала нормально читать данные. Но скорость ограниченна таймаутом.
Цитата
777777: Немного позанудствую: а так не проще?

Проще но при инлайне выкидывается чтение, а оно нужно.

Вообще тестирую на нескольких устройствах (пишу прошивку тестирования железа), на некоторых работает абсолютно нормально, на некоторых подвисает, похоже как раз на этих устройствах проблемы с памятью. Непонятно 2 момента:
1. как память slave может влиять на SPI
2. если ввести таймаут (см. выше) то память читается.

Go to the top of the page
 
+Quote Post
aesok
сообщение Oct 8 2010, 11:00
Сообщение #12


Знающий
****

Группа: Участник
Сообщений: 596
Регистрация: 26-05-06
Из: Москва
Пользователь №: 17 484



> 1. как память slave может влиять на SPI

никак не должна.

> 2. если ввести таймаут (см. выше) то память читается.

похоже на то что гдето происходит несанкционированое обращение к SPSR и/или к SPDR, скорее всего чтение.

Анатолий.

Сообщение отредактировал aesok - Oct 8 2010, 11:02
Go to the top of the page
 
+Quote Post
GDI
сообщение Oct 8 2010, 11:10
Сообщение #13


Профессионал
*****

Группа: Свой
Сообщений: 1 235
Регистрация: 14-05-05
Из: Санкт-Петербург
Пользователь №: 5 008



Цитата(Alex Truhin @ Oct 8 2010, 14:53) *
WP напрямую на мониторе питания, так что тут проблем нет

Вы посмотрите осциллографом, что у Вас творится на интерфейсе. У меня были похожие проблемы с 321-ми и тоже Мега128, точно так же зависало на чтении статуса (похоже это глюк у 321х, возможно у какой-то партии или у меги128), тогда я выяснил что на не подключенном WP плавает потенциал от 0 до питания и потому проблема проявлялась периодически. В зависимости от потенциала АТ45 просто не отвечала ничего на MISO (или ногу Busy не отпускала, я уже плохо помню), помогло прямое подключение ноги WP на питание.

P.S. Хотя, возможно, я ошибаюсь и у меня просто приходил статус, да он был всегда BUSY... В общем осцилл все равно не помешает.


--------------------
http://www.embedders.org Блоги разработчиков электроники.
Go to the top of the page
 
+Quote Post
alexeyv
сообщение Oct 8 2010, 13:08
Сообщение #14


Местный
***

Группа: Участник
Сообщений: 298
Регистрация: 26-01-09
Из: Пермь
Пользователь №: 43 940



А можно поинтересоваться что у Вас с пином SS (используется или нет и как настроен - вход или выход) ?
Go to the top of the page
 
+Quote Post
GDI
сообщение Oct 8 2010, 13:29
Сообщение #15


Профессионал
*****

Группа: Свой
Сообщений: 1 235
Регистрация: 14-05-05
Из: Санкт-Петербург
Пользователь №: 5 008



В сообщении №3 все же написано, про входы и выходы.


--------------------
http://www.embedders.org Блоги разработчиков электроники.
Go to the top of the page
 
+Quote Post
V_G
сообщение Oct 8 2010, 14:47
Сообщение #16


Профессионал
*****

Группа: Свой
Сообщений: 1 818
Регистрация: 15-10-09
Из: Владивосток
Пользователь №: 52 955



Цитата(alexeyv @ Oct 9 2010, 00:08) *
А можно поинтересоваться что у Вас с пином SS (используется или нет и как настроен - вход или выход) ?

Если вопрос по теме топика, то в мастер-режиме пин SS никак не задействован, его можно настраивать как угодно и манипулировать вручную. У меня на SPI сидят несколько устройств, для каждого вручную дергаю свой чипселект (он же SS)

Сообщение отредактировал V_G - Oct 8 2010, 14:48
Go to the top of the page
 
+Quote Post
=GM=
сообщение Oct 8 2010, 15:31
Сообщение #17


Ambidexter
*****

Группа: Свой
Сообщений: 1 589
Регистрация: 22-06-06
Из: Oxford, UK
Пользователь №: 18 282



Цитата(Alex Truhin @ Oct 7 2010, 09:33) *
uint8_t rx;
SPDR = tx;
while(!(SPSR & 0x80));
rx = SPDR;
при первом чтении все ОК, но при повторном чтении, на строке status = DF_SPI_RW(0x00); программа зависает, т.е. SPSR не взводиться

Явно есть проблема с периферией МК, нельзя ли оторвать SCLK и MOSI от чипа памяти и повторить тест?

Ещё интересует, почему вы читаете статус памяти, но не дожидаетесь готовности бита BUSY?
Вот кусок из старой библиотеки
Код
//================================================
// Ожидание готовности DataFlash,
// проверяем BUSY в регистре статуса
//------------------------------------------------
//аргументы: нет
//возвращает:значение регистра статуса
//================================================
xByte at45WaitReady(st_at45_Data *pntr)
{
xByte res=0;
SET_CS_DATAFLASH;                               //установим CS для DataFlash
txrxByteSpi(at45_StatusRegRead1, pntr->num);    //передаем номер команды
while (!(res&AT45BUSY))                         //ждем пока не установится
{
  res=txrxByteSpi(0, pntr->num);                //бит READY/nBUSY в регистре
}                                               //статуса DataFlash
RESET_CS_DATAFLASH;                             //сбросим CS для DataFlash
return(res);
}


--------------------
Делай сразу хорошо, плохо само получится
Go to the top of the page
 
+Quote Post
Alex Truhin
сообщение Oct 8 2010, 17:16
Сообщение #18





Группа: Новичок
Сообщений: 8
Регистрация: 13-04-10
Пользователь №: 56 609



Спасибо всем за рекомендации и советы, теперь только в понедельник посмотрю, отпишу результаты.
Цитата
=GM=: Ещё интересует, почему вы читаете статус памяти, но не дожидаетесь готовности бита BUSY?
Вот кусок из старой библиотеки

BUSY смотрю при переключении страниц, при запросе статуса его смотреть не нужно, это видно и из примеров atmel, и по логике, т.к. busy, согласно документации, можно проверять 2 способами, либо проверять на выводе (если он есть), либо проверять бит статуса.
Go to the top of the page
 
+Quote Post
Сергей Борщ
сообщение Oct 8 2010, 21:20
Сообщение #19


Гуру
******

Группа: Модераторы
Сообщений: 8 455
Регистрация: 15-05-06
Из: Рига, Латвия
Пользователь №: 17 095



Цитата(V_G @ Oct 8 2010, 17:47) *
Если вопрос по теме топика, то в мастер-режиме пин SS никак не задействован, его можно настраивать как угодно и манипулировать вручную.
Это не по теме топика (у автора он настроен на вывод), но для полноты картины: в мастер-режиме, будучи настроенным на ввод эта ножка используется:
Цитата
If SS is configured as an input, it must be held high to ensure Master SPI operation. If the SS pin is driven low by peripheral circuitry when the SPI is configured as a master with the SS pin defined as an input, the SPI system interprets this as another master selecting the SPI as a slave and starting to send data to it. To avoid bus contention, the SPI system takes the following actions:
1. The MSTR bit in SPCR is cleared and the SPI system becomes a slave. As a result of the SPI becoming a slave, the MOSI and SCK pins become inputs.
2. The SPIF flag in SPSR is set, and if the SPI interrupt is enabled, and the I-bit in SREG is set, the interrupt routine will be executed.


--------------------
На любой вопрос даю любой ответ
"Write code that is guaranteed to work, not code that doesn’t seem to break" (C++ FAQ)
Go to the top of the page
 
+Quote Post
demiurg_spb
сообщение Oct 10 2010, 12:41
Сообщение #20


неотягощённый злом
******

Группа: Свой
Сообщений: 2 746
Регистрация: 31-01-08
Из: Санкт-Петербург
Пользователь №: 34 643



Настройте ногу SS на выход, как Вам уже ранее неоднократно намекали.
Это стандартные грабли, на которые очень многие наступают:-)

Сори, увидел, что уже спросили Вас об этом (нога SS) и за Вас же ответили...


--------------------
“Будьте внимательны к своим мыслям - они начало поступков” (Лао-Цзы)
Go to the top of the page
 
+Quote Post
alexeyv
сообщение Oct 11 2010, 03:48
Сообщение #21


Местный
***

Группа: Участник
Сообщений: 298
Регистрация: 26-01-09
Из: Пермь
Пользователь №: 43 940



Цитата
А можно поинтересоваться что у Вас с пином SS (используется или нет и как настроен - вход или выход) ?


Цитата
Это не по теме топика (у автора он настроен на вывод),


Цитата
If SS is configured as an input, it must be held high to ensure Master SPI operation. If the SS pin is driven low by peripheral circuitry when the SPI is configured as a master with the SS pin defined as an input, the SPI system interprets this as another master selecting the SPI as a slave and starting to send data to it.


Это именно по теме топика и именно это я и хотел порекомендовать проверить!!!!!
Go to the top of the page
 
+Quote Post

2 страниц V   1 2 >
Reply to this topicStart new topic
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0

 


RSS Текстовая версия Сейчас: 26th June 2025 - 00:00
Рейтинг@Mail.ru


Страница сгенерированна за 0.01599 секунд с 7
ELECTRONIX ©2004-2016