Помощь - Поиск - Пользователи - Календарь
Полная версия этой страницы: PDC и SPI в AT91SAM7X
Форум разработчиков электроники ELECTRONIX.ru > Микроконтроллеры (MCs) > ARM
Pasha 111
Всем привет!

Решил для разгрузки процессора 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
Всем (кто юзает AT91) давно известно, что чипселект глючный у этих камней. Основная масса решает проблемы обычным "ногодрыганием" выделенной под CS линии.
DmitryM
Цитата(Pasha 111 @ Feb 18 2013, 10:15) *
Проблема вот в чём: если SPI работает через прерывания (AT91C_SPI_RDRF и AT91C_SPI_TXEMPTY), то все отправляются как надо, а если включить PDC и использовать прерывания AT91C_SPI_ENDRX и AT91C_SPI_ENDTX (при абсолютно тех же настройках самого контроллера SPI), то всё работает так же, и переписываются те же данные, но chip select не стробирует, а один раз устанавливается на низкий уровень в самом начале передачи буфера, а потом, в самом конце, опять возвращается на высокий уровень. Бит AT91C_SPI_LASTXFER, помещенный в каждую ячейку буфера для отправки, не помогает.

Дык это то как раз нормально, выставить чип-селект в начале блока и снять в конце. Если Вам нужно выставлять/снимать чип-селект на время каждого байта(слова), то только по выше приведенной рекомендации, обращаться по несуществующему чип-селекту.
Pasha 111
prottoss
Ну это всё понятно, конечно, но дёргание chip select'а через PIO делает бесполезным использование DMA.

DmitryM
Почему нормально? Такое происходит только если в регистре настройки конкретного chip select'а выставлен в 1 бит CSAAT (Chip Select Active After Transfer), только тогда при передаче байт один за другим chip select будет выставлен на низкий уровень, а на высокий вернётся только после передачи элемента данных, где выставлен в 1 бит LASTXFER (Last Transfer). Так всё и работает при реализации передачи через прерывания. При работе через PDC так почему-то не работает, бит LASTXFER ни на что не влияет.

Сейчас буду делать с данными-заглушками, так, по идее, должно работать, но способ не очень нравится.
prottoss
Цитата(Pasha 111 @ Feb 18 2013, 16:28) *
Ну это всё понятно, конечно, но дёргание chip select'а через PIO делает бесполезным использование DMA.
О как. Это как так???
Pasha 111
prottoss
Мне нужно отправлять по SPI данные сразу на несколько устройств. В одном случае я делаю один буфер и всё. А в случае управления chip select'ом через PIO я должен буфер разбить на несколько: по одному для каждого устройства, и отправлять их по очереди, чтобы chip select менять между отправками. Это лучше, конечно, чем отправлять через прерывания, но всё равно 1) неудобно и 2) не так эффективно.
DmitryM
Цитата(Pasha 111 @ Feb 18 2013, 13:28) *
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
Для просмотра полной версии этой страницы, пожалуйста, пройдите по ссылке.
Invision Power Board © 2001-2025 Invision Power Services, Inc.