Pasha 111 0 18 февраля, 2013 Опубликовано 18 февраля, 2013 · Жалоба Всем привет! Решил для разгрузки процессора AT91SAM7X128 перенести весь обмен данными (UART, SPI) на работу через PDC. Написал один код для работы с PDC (pdc.h и pdc.cpp). А код для работы с UART и SPI его, соответственно, использует. Так вот UART теперь работает просто замечательно, а вот SPI - нет. Настроен он у меня для работы с Variable Peripheral, т.е. номер chip select'а указывается прямо в регистре данных (да, учёл, что PDC в этом режиме SPI переписывает куски по 4 байта за раз - значения регистра отправки). Проблема вот в чём: если SPI работает через прерывания (AT91C_SPI_RDRF и AT91C_SPI_TXEMPTY), то все отправляются как надо, а если включить PDC и использовать прерывания AT91C_SPI_ENDRX и AT91C_SPI_ENDTX (при абсолютно тех же настройках самого контроллера SPI), то всё работает так же, и переписываются те же данные, но chip select не стробирует, а один раз устанавливается на низкий уровень в самом начале передачи буфера, а потом, в самом конце, опять возвращается на высокий уровень. Бит AT91C_SPI_LASTXFER, помещенный в каждую ячейку буфера для отправки, не помогает. Нашёл на просторах инета вот такой вот ответ: Using PDC, how to toggle SPI Chip Select between each data transfer? Здесь рекомендуют в буфере каждую вторую ячейку использовать как заглушку, отправляя данные на неподключённый chip select. Тогда chip select начнёт стробироваться. Но ведь нужно тогда в 2 раза бОльший массив иметь, да и вообще, какие-то костыли получаются. Как правильно сделать, чтобы SPI нормально через PDC работал в режиме Variable Peripheral? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
prottoss 0 18 февраля, 2013 Опубликовано 18 февраля, 2013 · Жалоба Всем (кто юзает AT91) давно известно, что чипселект глючный у этих камней. Основная масса решает проблемы обычным "ногодрыганием" выделенной под CS линии. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
DmitryM 0 18 февраля, 2013 Опубликовано 18 февраля, 2013 · Жалоба Проблема вот в чём: если SPI работает через прерывания (AT91C_SPI_RDRF и AT91C_SPI_TXEMPTY), то все отправляются как надо, а если включить PDC и использовать прерывания AT91C_SPI_ENDRX и AT91C_SPI_ENDTX (при абсолютно тех же настройках самого контроллера SPI), то всё работает так же, и переписываются те же данные, но chip select не стробирует, а один раз устанавливается на низкий уровень в самом начале передачи буфера, а потом, в самом конце, опять возвращается на высокий уровень. Бит AT91C_SPI_LASTXFER, помещенный в каждую ячейку буфера для отправки, не помогает. Дык это то как раз нормально, выставить чип-селект в начале блока и снять в конце. Если Вам нужно выставлять/снимать чип-селект на время каждого байта(слова), то только по выше приведенной рекомендации, обращаться по несуществующему чип-селекту. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Pasha 111 0 18 февраля, 2013 Опубликовано 18 февраля, 2013 · Жалоба prottoss Ну это всё понятно, конечно, но дёргание chip select'а через PIO делает бесполезным использование DMA. DmitryM Почему нормально? Такое происходит только если в регистре настройки конкретного chip select'а выставлен в 1 бит CSAAT (Chip Select Active After Transfer), только тогда при передаче байт один за другим chip select будет выставлен на низкий уровень, а на высокий вернётся только после передачи элемента данных, где выставлен в 1 бит LASTXFER (Last Transfer). Так всё и работает при реализации передачи через прерывания. При работе через PDC так почему-то не работает, бит LASTXFER ни на что не влияет. Сейчас буду делать с данными-заглушками, так, по идее, должно работать, но способ не очень нравится. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
prottoss 0 18 февраля, 2013 Опубликовано 18 февраля, 2013 · Жалоба Ну это всё понятно, конечно, но дёргание chip select'а через PIO делает бесполезным использование DMA.О как. Это как так??? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Pasha 111 0 18 февраля, 2013 Опубликовано 18 февраля, 2013 · Жалоба prottoss Мне нужно отправлять по SPI данные сразу на несколько устройств. В одном случае я делаю один буфер и всё. А в случае управления chip select'ом через PIO я должен буфер разбить на несколько: по одному для каждого устройства, и отправлять их по очереди, чтобы chip select менять между отправками. Это лучше, конечно, чем отправлять через прерывания, но всё равно 1) неудобно и 2) не так эффективно. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
DmitryM 0 18 февраля, 2013 Опубликовано 18 февраля, 2013 · Жалоба DmitryM Почему нормально? Такое происходит только если в регистре настройки конкретного chip select'а выставлен в 1 бит CSAAT (Chip Select Active After Transfer), только тогда при передаче байт один за другим chip select будет выставлен на низкий уровень, а на высокий вернётся только после передачи элемента данных, где выставлен в 1 бит LASTXFER (Last Transfer). Так всё и работает при реализации передачи через прерывания. При работе через PDC так почему-то не работает, бит LASTXFER ни на что не влияет. Это Вы неправильно понимаете CSAAT. Просто при работе без ДМА Вы не успеваете записать в TDR и чип селект снимается. Уменьшите частоту SPI и без PDC также чип-селект не будет дергаться на каждый байт(слово). Смотрите подробнее Figure 28-8 Peripheral Deselection Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться