atruhin 0 7 октября, 2010 Опубликовано 7 октября, 2010 · Жалоба 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? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
aesok 0 7 октября, 2010 Опубликовано 7 октября, 2010 · Жалоба Код настройки SPI. Функция DF_SPI_RW - это первая функция вызываемая из main ()? Анатолий. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
atruhin 0 7 октября, 2010 Опубликовано 7 октября, 2010 · Жалоба Код настройки: 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? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Lmx2315 2 7 октября, 2010 Опубликовано 7 октября, 2010 · Жалоба прошу прощения если не на то ссылку даю и если ничем особо новым тут не блесну - вот тут описание 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))) ; } Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
KSANDER 0 8 октября, 2010 Опубликовано 8 октября, 2010 · Жалоба Сижу вторые сутки нет ни каких идей. Хотя бы в принципе, отчего может не устанавливаться 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). Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
atruhin 0 8 октября, 2010 Опубликовано 8 октября, 2010 · Жалоба Эта ситуация не может возникнуть в Вашем случае?: 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 Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
GDI 0 8 октября, 2010 Опубликовано 8 октября, 2010 · Жалоба Ногу WP подтяните к питанию у АТ45. Можно просто соплю повесить, там нога питания соседняя, если корпус SO-8. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
aesok 0 8 октября, 2010 Опубликовано 8 октября, 2010 · Жалоба Как запрограмирован фьюз M103C? Как скомпилировалась строка rx = SPDR;? Проверте везде не только в функции DF_SPI_RW, но и во всех местах где она проинлайнилась. не выкинул ли ее компилятор. Есть ли в других местах программы обращение к регистру SPDR? Поставте в отладчике остановку по обращению к адресу SPDR, возможно в него кто то пишет по указателю. Состояние бита WCOL в SPSR? Анатолий. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
777777 0 8 октября, 2010 Опубликовано 8 октября, 2010 · Жалоба А не сбрасывает ли кто SPE случайно? Может просто ноль в SPCR пишет? 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; } Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Сергей Борщ 119 8 октября, 2010 Опубликовано 8 октября, 2010 · Жалоба А не сбрасывает ли кто SPE случайно?Можно еще спросить - не настроена ли на ввод нога SS и не подается ли на нее низкий уровень? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
atruhin 0 8 октября, 2010 Опубликовано 8 октября, 2010 · Жалоба Ну по порядку: 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. если ввести таймаут (см. выше) то память читается. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
aesok 0 8 октября, 2010 Опубликовано 8 октября, 2010 (изменено) · Жалоба > 1. как память slave может влиять на SPI никак не должна. > 2. если ввести таймаут (см. выше) то память читается. похоже на то что гдето происходит несанкционированое обращение к SPSR и/или к SPDR, скорее всего чтение. Анатолий. Изменено 8 октября, 2010 пользователем aesok Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
GDI 0 8 октября, 2010 Опубликовано 8 октября, 2010 · Жалоба WP напрямую на мониторе питания, так что тут проблем нет Вы посмотрите осциллографом, что у Вас творится на интерфейсе. У меня были похожие проблемы с 321-ми и тоже Мега128, точно так же зависало на чтении статуса (похоже это глюк у 321х, возможно у какой-то партии или у меги128), тогда я выяснил что на не подключенном WP плавает потенциал от 0 до питания и потому проблема проявлялась периодически. В зависимости от потенциала АТ45 просто не отвечала ничего на MISO (или ногу Busy не отпускала, я уже плохо помню), помогло прямое подключение ноги WP на питание. P.S. Хотя, возможно, я ошибаюсь и у меня просто приходил статус, да он был всегда BUSY... В общем осцилл все равно не помешает. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
alexeyv 0 8 октября, 2010 Опубликовано 8 октября, 2010 · Жалоба А можно поинтересоваться что у Вас с пином SS (используется или нет и как настроен - вход или выход) ? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
GDI 0 8 октября, 2010 Опубликовано 8 октября, 2010 · Жалоба В сообщении №3 все же написано, про входы и выходы. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться