|
|
  |
stm32f407 SPI обнаружил косяк |
|
|
|
Nov 16 2012, 15:14
|
Местный
  
Группа: Свой
Сообщений: 252
Регистрация: 9-10-08
Из: Московская обл.
Пользователь №: 40 797

|
наверное не просто так в RM написано Цитата Note: Do not use the BSY flag to handle each data transmission or reception. It is better to use the TXE and RXNE flags instead.
|
|
|
|
|
Nov 16 2012, 18:34
|
Местный
  
Группа: Участник
Сообщений: 226
Регистрация: 10-07-09
Пользователь №: 51 126

|
Цитата(SasaVitebsk @ Nov 16 2012, 13:45)  При инициализации с делителем на 64 (с другими не проверял). SPI3 (с другими не проверял). stm407 на 168МГц (с другими не проверял). Это есть во всех STM32... и ни какой это не косяк... "Читать даташит до, а не после!"(С) Цитата Note: 1 During discontinuous communications, there is a 2 APB clock period delay between the
write operation to SPI_DR and the BSY bit setting. Цитата После записи в регистр DR необходимо выждать задержку до проверки флага BSY в регистре SR. Иначе байт может потерятся (затерется следующим). То есть флаг занятости выскакивает с задержкой. Причём задержка приличная, успеваю выйти и войти в процедуру. После установки задержки всё устаканилось. Если STM32F4 сидит на 168MHz, a APB SPI3 42MHz... сам и посчитай... Всё правильно... никаких косяков и нет...
Сообщение отредактировал HHIMERA - Nov 16 2012, 18:37
|
|
|
|
|
Nov 16 2012, 19:09
|
Гуру
     
Группа: Свой
Сообщений: 2 712
Регистрация: 28-11-05
Из: Беларусь, Витебск, Строителей 18-4-220
Пользователь №: 11 521

|
Цитата(HHIMERA @ Nov 16 2012, 22:34)  никаких косяков и нет... C учётом последствий - это просто косяк описанный в даташите. Там, кстати 2 APB. APB1 (SPI3) и APB2. APB1 по-моему у меня /2. === Спорить не буду - сложно посчитать будет. Да и не это главное... Написал, чтобы народ обратил внимание. Я не исключаю, что в другой периферии не может оказаться аналогичных проблем. Думаю из-за значительной скорости процессора. Я не спорю, это можно описать как "особенности работы с узлами МК" ... Так, у меня уже проявились "особенности" при работе с I2C и SPI. Так это только начало. Этот SPI работает с АЦП, а SPI1 будет с датафлэшем работать... Если там ещё особенности вылезут - опишу ... ))
|
|
|
|
|
Nov 16 2012, 22:37
|
Знающий
   
Группа: Участник
Сообщений: 643
Регистрация: 29-05-09
Из: Германия
Пользователь №: 49 725

|
Цитата(Flexz @ Nov 16 2012, 17:14)  наверное не просто так в RM написано Поддерживаю. Для полнодуплексного (даже если только передача нужна) SPI завершение передачи нужно проверять по... RXNE (и забыть о TXE или BSY, т.к. STM32F не поддерживает аппаратное формирование SS в режиме мастера!). Тогда будет абсолютная уверенность, что байт ушел, а следующий его не затрет по пути: ведь пока байт выдвигается по MOSI, входящий байт вдвигается по MISO тем же тактовым сигналом. Это означает, что флаг RXNE все равно возникнет, пусть позже TXE, зато наверняка после последнего такта. Нужно помнить чистить RXNE путем чтения DR перед записью туда: 1. Прочесть DR. 2. Записать в DR байт для передачи. 3. Ждать RXNE (будь-то тупо или путем реакции на прерывание). 4. Перейти к п.1., если еще есть данные для передачи.
Сообщение отредактировал KnightIgor - Nov 16 2012, 22:44
|
|
|
|
|
Nov 16 2012, 23:22
|

embarrassed systems engineer
    
Группа: Свой
Сообщений: 1 083
Регистрация: 24-10-05
Из: Осокорки
Пользователь №: 10 038

|
Цитата(KnightIgor @ Nov 17 2012, 00:37)  Поддерживаю. Для полнодуплексного (даже если только передача нужна) SPI завершение передачи нужно проверять по... RXNE (и забыть о TXE или BSY, т.к. STM32F не поддерживает аппаратное формирование SS в режиме мастера!). Тогда будет абсолютная уверенность, что байт ушел, а следующий его не затрет по пути: ведь пока байт выдвигается по MOSI, входящий байт вдвигается по MISO тем же тактовым сигналом. Это означает, что флаг RXNE все равно возникнет, пусть позже TXE, зато наверняка после последнего такта. Нужно помнить чистить RXNE путем чтения DR перед записью туда: Делал я так. Побочный эффект - обмен не непрерывный, между байтами пропуски получаются. При тактовой 15МГц, еле на 1МБайт/сек выходило. Пришлось сделать такой вариант: CODE IO_CALL_TYPE DWORD IO_CALL_OPTION io_at45_read(void) { PSTM_SPI pspi = _AT_SPI_; // // В целях сохранения быстродействия не производим проверку // синхроресурса в функциях самого нижнего уровня // // IO_ASSERT( at45_mutex.holder == tn_curr_run_task, "AT45 synch failure"); // for(;;) { DWORD stat; // // Значительно более быстрый вариант - ждать TXE и немедленно // запускать новый цикл на SPI если буфер передатчика готов // Иначе контроллер делает паузы между символами. Чтобы не // потерять принимаемый символ при вытеснении потока, запуск // осуществляем при запрещенных прерываниях // stat = pspi->sSPI_SR; if (stat & bSPI_TXE) { DWORD lock, ret;
lock = hal_lock_interrupt(); pspi->sSPI_DR = 0xFF;
for(;;) { // // Ждем завершения предыдущего цикла // и забираем принятые данные по готовности // if (stat & bSPI_RXNE) { ret = pspi->sSPI_DR; break; } stat = pspi->sSPI_SR; } hal_unlock_interrupt(lock); return ret & 0xFF; } } }
Скорость выросла раза в 1.5, DMA не пробовал - не очень подходт для задачи.
|
|
|
|
|
Nov 16 2012, 23:23
|
Местный
  
Группа: Участник
Сообщений: 226
Регистрация: 10-07-09
Пользователь №: 51 126

|
Цитата(KnightIgor @ Nov 17 2012, 02:37)  Поддерживаю. Да всё там просто... Всё скрупулёзно и последовательно расписано в даташите... Нужно просто воспринять TXE, RXNE и BSY так, как их задумал производитель... и обратить их во благо своё... Вся эта чехарда с флагами, ИМХО, мнимая и надуманная...
Сообщение отредактировал HHIMERA - Nov 16 2012, 23:27
|
|
|
|
|
Dec 18 2012, 13:47
|
Местный
  
Группа: Участник
Сообщений: 280
Регистрация: 2-11-08
Пользователь №: 41 333

|
Цитата(KnightIgor @ Nov 17 2012, 02:37)  1. Прочесть DR. 2. Записать в DR байт для передачи. 3. Ждать RXNE (будь-то тупо или путем реакции на прерывание). 4. Перейти к п.1., если еще есть данные для передачи. Не получается: 1. Прочесть DR - после этого флаг RXNE не устанавливается (У меня разрешены прерывания по RXNE). Если сперва что-то записать в DR, то тогда RXNE устанавливается и происходит прерывание. Еще вопрос как я понимаю при работе с SPI необходимо Мастером всегда толкать данные? Например data-flash at45db имеет команду для чтения manufacture id и device id длиной 1 байт=0x9FH, а ответ 6 байт, т.е. после подачи первого байта я должен еще подать 5 фиктивных байт?
Сообщение отредактировал sidy - Dec 18 2012, 13:48
|
|
|
|
|
Dec 18 2012, 17:04
|

Twilight Zone
  
Группа: Свой
Сообщений: 454
Регистрация: 17-02-09
Из: Челябинск
Пользователь №: 44 990

|
Цитата(sidy @ Dec 18 2012, 17:47)  Не получается: 1. Прочесть DR - после этого флаг RXNE не устанавливается (У меня разрешены прерывания по RXNE). Если сперва что-то записать в DR, то тогда RXNE устанавливается и происходит прерывание.
Еще вопрос как я понимаю при работе с SPI необходимо Мастером всегда толкать данные? Например data-flash at45db имеет команду для чтения manufacture id и device id длиной 1 байт=0x9FH, а ответ 6 байт, т.е. после подачи первого байта я должен еще подать 5 фиктивных байт? В любом случае микросхема SPI памяти не будет выталкивать из себя данные сама, для чтения нужно слать что-нибудь мастером, какие либо незначащие байты.
--------------------
Magic Friend
|
|
|
|
|
  |
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0
|
|
|