Пришло время рассмотреть последовательный интерфейс передачи данных SPI в контроллерах tms320. Штука это безусловно полезная и нужная, без неё невозможно представить себе уже наверное ни одно современной устройство.
Вот так выглядит структура модуля SPI в tms320:
Как видно для работы с SPI нам понадобиться настроить GPIO, прерывания и сам модуль.
Говоря о SPI сразу упомяну о возможных режимах работы. Настройки тут (грубо говоря) только две: фаза и полярность.
Фаза указывает по какому фронту будет происходить выборка данных, а полярность – уровень с которого «начинается» сигнал синхронизации.
Соответственно может быть 4 варианта работы.
С настройкой полярность=0 и фаза=0
С настройкой полярность равна=1 фаза=0
С настройков полярность=0 фаза=1
С настройкой полярность=1 фаза=1
На изображениях вы видите осциллограммы 4 режимов работы SPI при передаче 0х1234.
Теперь же давайте перейдем к настройке сего в tms320.
Сначала настроим ножки для работы с SPI (модуль GPIO).
EALLOW; // включаем подтяжку GpioCtrlRegs.GPAPUD.bit.GPIO16 = 0; //SPISIMOA GpioCtrlRegs.GPAPUD.bit.GPIO17 = 0; //SPISOMIA GpioCtrlRegs.GPAPUD.bit.GPIO18 = 0; //SPICLKA GpioCtrlRegs.GPAPUD.bit.GPIO19 = 0; //SPISTEA // настраиваем ножки как асинхронные GpioCtrlRegs.GPAQSEL2.bit.GPIO16 = 3; // асинхронный вход GPIO16 (SPISIMOA) GpioCtrlRegs.GPAQSEL2.bit.GPIO17 = 3; // асинхронный вход GPIO17 (SPISOMIA) GpioCtrlRegs.GPAQSEL2.bit.GPIO18 = 3; // асинхронный вход GPIO18 (SPICLKA) GpioCtrlRegs.GPAQSEL2.bit.GPIO19 = 3; // асинхронный вход GPIO19 (SPISTEA) // настраиваем ножки как SPI GpioCtrlRegs.GPAMUX2.bit.GPIO16 = 1; // настраиваем GPIO16 как SPISIMOA GpioCtrlRegs.GPAMUX2.bit.GPIO17 = 1; // настраиваем GPIO17 как SPISOMIA GpioCtrlRegs.GPAMUX2.bit.GPIO18 = 1; // настраиваем GPIO18 как SPICLKA GpioCtrlRegs.GPAMUX2.bit.GPIO19 = 1; // настраиваем GPIO19 как SPISTEA EDIS;
Если возникают трудности идем в статью о GPIO.
После того, как ножки стали работать как выводы модуля SPI можно приступать к настройке самого модуля.
Для этого в наличии регистр SPICCR:
Тут нам нужно указать полярность (CLKPOLARITY), размер данных (SPICHAR) и сбросить SPI.
Бит SPI SW RESET необходимо выставить в 0 до редактирования настроек, а после окончания редактирования вернуть в 1. Это позволяет избежать непредвиденных эффектов при перенастройке «налету». Пока бит 0 данные не в сдвиговых регистрах SPI изменятся не будут.
Размер данных указывает при помощи поля SPICHAR, которое состоит из 4 бит.
Соответственно вы можете произвольно выбрать длину слова от 1 до 16 бит.
В данном регистре присутствует магическое поле для отладки SPILBK. Установив данный бит вы закорачиваете передатчик и приемник (MOSI и MISO), что позволяет отладить код не имея второго устройства.
Вторым регистром на пути настройки SPI в микроконтроллерах TMS является регистр SPICTL.
Тут мы можем настроить фазу (CLOCK PHASE), режим работы (MASTER / SLAVE) и прерывания.
В этом регистре есть хитрый бит TALK, который позволяет прекратить передачу путем перевода передатчика SPI в высокоимпедансное состояние.
С остальным думаю должно быть понятно.
Для настройки частоты предусмотрен регистр SPIBRR
В принципе это просто делитель системной частоты. Формулу можно увидеть на картинке выше или же в документации.
Когда настройки сделаны нужно как-то контролировать модуль. Для этого есть регистр SPIST
Тут можно найти разнообразные флаги состояния SPI.
В техасском spi есть буфер FIFO. В зависимости от контроллера глубина может различаться.
Как видно из структуры на самом деле есть два буфера. Один на прием, другой на передачу.
Для настройки сих благ предусмотрены специальные регистры. В принципе в простейшем случае Вы и вообще можете не использовать FIFO.
Для настройки передатчика предусмотрен регистр SPIFFTX:
Тут нам интересен бит SPIRST для сброса регистров FIFO.
SPIFFENA – включает/отключает улучшения данного модуля.
TXFIFO Reset — сбрасывает указатель на FIFO в 0 и удерживает в состоянии сброса.
Также тут в наличии регистр статуса (TXFFST), флаг наличия необработанного прерывания (TXFFINT), бит для сброса флага прерывания (TXFFINT CLR), бит разрешения прерывания от данного модуля (TXFFIENA) и поле TXFFIL для настройки события для генерации прерывания (по совпадению со статусом FIFO).
Для настройки FIFO приемника предусмотрен регистр SPIFFRX:
Тут есть флаг RXFFOVF переполнения FIFO и RXFFOVF CLR – для очистки флага RXFFOVF.
RXFIFO Reset – сбрасывает FIFO.
RXFFST – статус FIFO (количество принятых слов данных).
RXFFINT – флаг наличия необработанного прерывания.
RXFFINT CLR – бит для сброса флага RXFFINT
RXFFIENA – разрешение генерации прерывания
RXFFIL – прерывание генерируется если получено больше или столько же слов как в этом поле.
Для управления регистрами FIFO есть регистр SPIFFCT. Тут вы можете задать задержку между каждой операцией между сдвиговым регистром и FIFO.
Вот так будет выглядеть простейшая функция инициализации SPI без прерываний в tms320:
void spi_init() { // настраиваем ножки для работы с SPI spi_gpio_init(); SpiaRegs.SPICCR.all =0x000F; // 16-bit char bits SpiaRegs.SPICTL.all =0x0006; // SPI MASTER и разрешаем передачу SpiaRegs.SPIBRR = 0x007F; // настройка частоты SpiaRegs.SPICCR.all =0x008F; // SPI SW RESET | 16bit SpiaRegs.SPICCR.bit.SPILBK = 0; // петля для отладки откл SpiaRegs.SPIPRI.bit.FREE = 1; // делаем так чтобы точки останова не мешали работе модуля // настройка регистров FIFO SpiaRegs.SPIFFTX.all=0xE040; // SPIRST | SPIFFENA | TXFIFO Reset | TXFFINT CLR SpiaRegs.SPIFFRX.all=0x2044; // RXFIFO Reset | RXFFINT CLR SpiaRegs.SPIFFCT.all=0x0; // настройка полярности и фазы SpiaRegs.SPICTL.bit.CLK_PHASE = 0; SpiaRegs.SPICCR.bit.CLKPOLARITY = 0; }
Тут вы можете скачать проект: https://www.dropbox.com/s/63cmezh5ohuc5dd/tms320_spi.zip
Документация на модуль SPI: https://www.dropbox.com/s/ki282rlhkzmll0w/tms320_spi.pdf