Здесь приведен перевод документации по библиотеке компании Analog Devices, реализующей физический драйвер устройства UART [8] (ADI_UART), который исползует каналы DMA (документация в файле Blackfin\docs\drivers\uart\adi_uart_dma.pdf, находящимся в каталоге установки системы VisualDSP++). У драйвера нет никаких аппаратных привязок к определенному типу процессора (поскольку большинство, если не все процессоры Blackfin имеют на борту встроенный интерфейс UART), и тестировался на процессорах ADSP-BF533, ADSP-BF537 и плате разработчика ADSP-BF561 EZ-Kit Lite.
Драйвер UART реализован в двух версиях - работающий под управлением DMA и прерываний, и работающий под управлением только прерываний. Есть два модуля исходного кода - adi_uart_dma.c и adi_uart_int.c, предназначенных для каждой версии драйвера. Использование в проекте модуля adi_uart.c по умолчанию приведет к сборке проекта с драйвером, использующим только прерывания (без DMA).
Этот документ описывает только версию драйвера UART на основе DMA. Чтобы проект приложения использовал эту версию драйвера, в проекте должен быть подключен модуль adi_uart_dma.c, и должна использоваться точка входа ADIUARTDmaEntryPoint при запуске драйвера UART.
Примечание: имеется аналогичный драйвер UART, не использующий каналы DMA, см. файл Blackfin\docs\drivers\uart\adi_uart.pdf (см. также [7]). Примеры кода, использующие драйвер UART с прерываниями и драйвером UART с DMA, можно найти в поддиректориях Blackfin\Examples\ каталога установки VisualDSP++ (ищите файлы *.c и *.cpp, в которых подключается заголовочный файл adi_uart.h). Драйвер UART на основе DMA целесообразно использовать в протоколах, использующих в передаче и приеме блоки большого, фиксированного размера. Другую версию драйвера UART, работающую на основе прерываний [7], лучше использовать для консольного интерфейса, обрабатывающего команды пользователя - когда передаются либо одиночные символы, либо не предсказуемое заранее количество символов.
[Используемые файлы]
Все упомянутые здесь файлы находятся в поддиректориях каталога установки системы программирования VisualDSP++. Указанные пути для подключаемых файлов начинаются с директории %ProgramFiles%\Analog Devices\VisualDSP 5.0\Blackfin\include, а для файлов исходного кода с директории %ProgramFiles%\Analog Devices\VisualDSP 5.0.
Подключаемые файлы. Исходный код драйвера подключает следующие заголовочные файлы:
services/services.h. Здесь содержатся все определения, прототипы функций и т. д. для всей библиотеки Системных Служб (System Services Library, SSL).
drivers/adi_dev.h. Здесь содержатся все определения, прототипы функций и т. д. для Менеджера Устройств (Device Manager) и общая информация по модели Драйвера Устройства.
drivers/uart/adi_uart.h. Здесь содержатся коды всех команд, событий и значений возврата для API драйвера устройства UART.
Исходный код. Исходный код драйвера UART содержится в файле Blackfin/lib/src/drivers/uart/adi_uart_dma.c. В этом модуле определен макрос ADI_UART_DMA, и подключается весь исходный код из материнского модуля adi_uart.c. Весь код написан на языке C. Для драйвера не используется никаких функций, написанных на ассемблере.
Код драйвера UART не использует никакие низкоуровневые физические драйверы устройств, он сам фактически является таким драйвером.
[Ресурсы, требуемые для DMA-драйвера UART]
Драйверы устройств обычно требуют для своей работы некоторое количество системных ресурсов (уровни приоритета прерываний IVG, каналы DMA, память). В этом разделе описаны ресурсы, которые требует для себя драйвер UART.
За исключением специально указанных ниже случаев, этот драйвер использует Системные Службы для доступа к любой требуемой аппаратуре процессора и управления этой аппаратурой. Информация в этой секции может быть полезна в определении ресурсов, которые нужно выделить для драйвера UART со стороны Системных Служб, наподобие количества обработчиков прерывания или количества используемых каналов DMA и т. п.
По той причине, что в Драйверах Устройств и Системных Службах не используется динамическое выделение памяти, вся память для Драйверов Устройств и Системных Служб должна быть явно предоставлена приложением. Библиотека Драйверов Устройств и Системных Служб предоставляет специальные макросы, которые можно использовать в приложении для вычисления необходимого количества базовой памяти и/или количества дополнительной памяти, которая требуется для поддержки нужного функционала служб. Память для Менеджера Устройств и Системных Служб предоставляется специальными функциями инициализации соответствующего API (adi_xxx_Init(), где вместо xxx указывается мнемонический идентификатор службы. Например для Менеджера Устройств это будет функция adi_dev_Init()).
Прерывания. За исключением случаев, когда это отменено соответствующими командами, драйвер UART по умолчанию использует привязку групп прерываний IVG и их настройку. В результате будет использовано до 3 ресурсов прерываний для каждого открытого устройства UART, если оно открыто в одно направлении. Если устройство UART открыто в двунаправленном режиме, то будет использоваться 5 ресурсов прерываний. Драйвер UART подцепляет следующие обработчики прерываний:
Transmit (Tx) Interrupt. Это прерывание подцепляется, когда UART открыт для исходящего или двунаправленного потока данных. Прерывание подцепляется в момент открытия UART (в функции adi_dev_Open()). Любые изменения привязки IVG для UART transmit interrupt должно быть сделано до того, как будет открыт UART. Прерывание отцепляется, когда устройство UART закрывается (adi_dev_close()).
Receive (Rx) Interrupt. Это прерывание подцепляется, когда UART открывается для входящего или двунаправленного потока данных. Прерывание подцепляется в момент открытия UART (в функции adi_dev_Open()). Любые изменения привязки IVG для UART receive interrupt должно быть сделано до того, как будет открыт UART. Прерывание отцепляется, когда устройство UART закрывается (adi_dev_close()).
Внимание: для обработки поступающих на вход UART данных имеет большое значение, каким образом будет запускаться функция обратного вызова (callback) приема. Имеется 2 возможности - во-первых, немедленный вызов callback прямо из обработчика прерывания, и во-вторых, отложенный вызов callback с помощью Менеджера отложенных функций обратного вызова [6] (Deferred Callback, DCB). Выбор из этих двух вариантов очень важен. Например, если необходима быстрая обработка следующих друг за другом без задержки символов (например, 3-байтовые ESC-последовательности, которые посылает клиент терминала при нажатиях в консоли клавиш со стрелками), то нужно обязательно использовать вариант вызова callback напрямую из обработчика прерывания, без использования Менеджера DCB. Иначе приходящие символы будут случайным образом теряться, потому что драйвер UART не обеспечивает внутреннюю промежуточную буферизацию символов. Выбор из этих двух возможностей (callback в контексте ISR или в контексте DCB) делается в момент открытия драйвера вызовом функции adi_dev_Open (подробнее см. [3, 5]).
Error/Line Status Interrupt. Это прерывание подцепляется/отцепляется, когда приложение передает драйверу команду ADI_UART_CMD_SET_LINE_STATUS_EVENTS. По умолчанию прерывания состояния линии (line status interrupts) не генерируются, так что если генерация прерываний изменения состояния линии нужна, то это должно быть включено командой ADI_UART_CMD_SET_LINE_STATUS_EVENTS. Когда функция adi_dev_Control() получает эту команду с прилагающимся аргументом TRUE, то разрешаются прерывания статуса линии, и подцепляется обработчик прерывания к цепочке IVG. Когда функция adi_dev_Control() получает эту команду с прилагающимся аргументом FALSE, то прерывания статуса линии запрещаются, и обработчик прерывания отцепляется от цепочки IVG. Если прерывание статуса линии разрешено и подцеплено, то оно будет запрещено и автоматически отцеплено, когда драйвер закрывается (adi_dev_Close()).
Timer Interrupt. Используется только в время автодетекта скорости (функция Autobaud detection) и только через службу управления таймерами (Timer Control service [1]). Для дополнительной информации см. ниже секцию "Таймер".
DMA. Эта версия драйвера UART использует два канала DMA, один для передачи, другой для приема. Версию без DMA целесообразно использовать для коротких пересылок блоков данных неопределенной длины и одиночных байт - например, для организации консоли управления или для вывода отладочной информации. Имеется также версия драйвера UART с поддержкой DMA.
Таймер. Драйвер UART использует ресурсы таймера только для функции автоматического определения скорости (autobaud detection). Если автоопределение скорости не используется, то не используются ресурсы таймера. Если используется функция автодетекта скорости, то используется таймер, как это описано ниже.
Когда передается команда ADI_DEV_CMD_AUTOBAUD, драйвер UART использует службу таймеров (Timer Control service [1]), чтобы получить доступ к ресурсам таймера, с которым связан определенный интерфейс UART. Например для процессора ADSP-BF533 для функции автодетекта скорости UART используется Timer1. Этот выбор таймера фиксирован моделью процессора, и его невозможно поменять. В ответ на команду драйвер сбрасывает таймер, устанавливает callback на таймер и конфигурирует таймер подходящим образом для поддержки функции autobaud detection. Таймер используется до завершения процедуры автодетекта, после чего таймер запрещается, callback удаляется и таймер освобождается для повторного использования в приложении для каких-то других целей.
Часы реального времени (RTC). Драйвер устройства UART не использует какие-либо службы часов реального времени.
Программируемые флаги. Драйвер UART не использует явно какие-либо выводы процессора (GPIO, компания Analog Devices почему-то называет их программируемыми флагами). Однако, на большинстве процессоров вход и выход UART мультиплексируется с программируемыми выводами GPIO. Пользователь должен сам убедиться в том, что эти выводы, используемые для UART, не конфликтовали с использованием выводов GPIO, и наоборот.
Используемые выводы. Всего интерфейс UART для соединения с внешним миром использует 2 сигнальных провода - прием (RX) и передача (TX) плюс общий провод земля (GND). На устройствах, где используется мультиплексирование функций на выводах, драйвер UART использует службу управления портами (Port Control service), чтобы автоматически сконфигурировать выводы так, чтобы они использовались для UART следующим образом:
• Двунаправленный поток данных - для использования UART конфигурируются оба вывода сигнала, и прием и передача. • Только входящий поток данных - для использования UART конфигурируется только вывод приема. • Только исходящий поток данных - для использования UART конфигурируется только вывод передачи.
Конфигурирование происходит в момент открытия UART (в функции adi_dev_Open()).
[Функции, поддерживаемые драйвером UART]
Направление потоков данных. Драйвер поддерживает приведенные в таблице ниже варианты настройки для направления потока данных. ADI_DEV_DIRECTION это тип перечисления enum, задающий варианты направления данных (определен в заголовочном файле Blackfin\include\drivers\adi_dev.h).
Таблица 2. Поддерживаемые направления потока данных для устройства UART (Dataflow Directions).
ADI_DEV_DIRECTION
Описание
ADI_DEV_DIRECTION_INBOUND
Поддерживает прием данных в устройство.
ADI_DEV_DIRECTION_OUTBOUND
Поддерживает передачу данных из устройства.
ADI_DEV_DIRECTION_BIDIRECTIONAL
Поддерживаются оба направления данных.
Методы поддержки потока данных. Поддерживаемые методы организации потока данных перечислены в таблице ниже. ADI_DEV_MODE это тип перечисления enum, задающий варианты предоставления буферов для данных (определен в заголовочном файле Blackfin\include\drivers\adi_dev.h).
Таблица 3. Поддерживаемые методы организации потока данных.
ADI_DEV_MODE
Описание
ADI_DEV_MODE_CHAINED
Поддерживает метод цепочек буферов.
ADI_DEV_MODE_CHAINED_LOOPBACK
Поддерживает метод цепочек буферов с переходом на начало цепочки.
Типы буфера. Эта версия драйвера поддерживает только тип буфера одномерный линейный ADI_DEV_1D_BUFFER. Поле pAdditionalInfo структуры буфера ADI_DEV_1D_BUFFER игнорируется.
Идентификаторы команд. В этой секции перечислены команды, поддерживаемые драйвером. Команды делятся на 3 секции. Первая описывает команды, поддерживаемые напрямую Менеджером Устройств. Следующая секция описывает общие поддерживаемые драйвером команды (относящиеся ко всем драйверам, не только к UART). Последняя секция описывает специфические для драйвера UART команды.
Команды посылаются в драйвер устройства через функцию adi_dev_Control(). Она принимает 3 аргумента:
DeviceHandle. Этот параметр типа ADI_DEV_DEVICE_HANDLE, который уникально идентифицирует драйвер устройства. Это дескриптор (handle), предоставленный клиенту при вызове функции adi_dev_Open(). CommandID. Этот параметр типа u32, он задает идентификатор команды. Value. Этот параметр типа void *, смысл которого зависит от значения идентификатора команды.
Ниже будут перечислены идентификаторы команд, поддерживаемые драйвером, и будет объяснено значение команды и описание соответствующего каждой команде параметра Value.
Команды, перечисленные ниже, поддерживаются напрямую Менеджером Устройств, и не передаются драйверу для обработки. Таким образом, все драйверы устройств поддерживают эти команды.
ADI_DEV_CMD_TABLE. Обозначает передачу драйверу таблицы команд. Value – ADI_DEV_CMD_VALUE_PAIR *.
ADI_DEV_CMD_END. Обозначает конец пар таблицы команд. Value игнорируется.
ADI_DEV_CMD_PAIR. Передана одна пара команд. Value – ADI_DEV_CMD_PAIR *.
ADI_DEV_CMD_SET_SYNCHRONOUS. Разрешает/запрещает синхронный режим для драйвера. Value – TRUE/FALSE.
Идентификаторы команд, описанные в этой секции, являются общими для многих драйверов устройств. Ниже в списке перечислены всех общие идентификаторы команд (command ID), которые поддерживаются драйвером UART.
ADI_DEV_CMD_SET_DATAFLOW_METHOD. Задает используемый метод потока данных устройства. Value – одно из поддерживаемых значений перечисления ADI_DEV_MODE (таблица 3).
ADI_DEV_CMD_SET_DATAFLOW. Разрешает/запрещает поток данных через устройство. Value – TRUE/FALSE.
ADI_DEV_CMD_GET_2D_SUPPORT. Позволяет вызывающему коду определить, может ли драйвер поддерживать двумерные (2D) буферы. Драйвер UART всегда возвратит FALSE для этой команды. Value – u32*, указывает на ячейку, куда помещается ответ (TRUE/FALSE).
ADI_DEV_CMD_SET_ERROR_REPORTING. Разрешает/запрещает сообщения от ошибках со стороны драйвера устройства. Эта команда используется, чтобы разрешить или запретить генерацию событий изменения состояния линии статуса; будут генерироваться события overrun, parity, ошибок фрейма и поступление break. Value – TRUE/FALSE.
ADI_DEV_CMD_GET_PERIPHERAL_DMA_SUPPORT. Позволяет вызывающему коду определить, поддерживается ли драйвер периферийным DMA. В ответ на эту команду драйвер всегда вернет TRUE. Value – u32*, указывает на ячейку, куда помещается ответ (TRUE/FALSE).
Идентификаторы команд, перечисленные ниже, поддерживаются и обрабатываются драйвером UART, они уникальны именно для этого драйвера устройства.
ADI_UART_CMD_SET_DATA_BITS. Устанавливает количество бит данных фрейма UART. Переданное значение задает количество бит данных одной элементарной посылки. Допустимые значения 5, 6, 7 или 8 (обычно используется 8). Value – u16 (количество бит).
ADI_UART_CMD_SET_STOP_BITS. Устанавливает количество стоп-битов, определяющих конец фрейма. Значение 1 устанавливает один стоп-бит, значение 2 устанавливает два стоп-дита для количества бит данных фрейма, не равного 5, и 1.5 стоп-бита для длины фрейма 5 бит. Value – u16 (количество стоп-битов).
ADI_UART_CMD_SET_PARITY. Устанавливает тип проверки на четность данных (parity checking) - четность или нечетность. Обратите внимание, что эта команда всего лишь задает режим четности, но не разрешает саму проверку четности (см. ниже команду ADI_UART_CMD_ENABLE_PARITY). Значение – четное число для проверки на четность, нечетное число для проверки на нечетность.
ADI_UART_CMD_ENABLE_PARITY. Разрешает проверку данных по четности (parity checking). Эта команда включает одновременно генерацию бита четности при передаче и проверку бита четности на приеме. События статуса линии также должны быть включены (см. ниже команду ADI_UART_CMD_SET_LINE_STATUS_EVENTS), чтобы работало оповещение о событиях ошибок четности. Value – TRUE включает функцию проверки четности, FALSE выключает проверку четности.
ADI_UART_CMD_SET_LINE_STATUS_EVENTS. Разрешает/запрещает генерацию событий статуса линии (а также сообщений об ошибках) для приложения. Когда оповещение о событиях статуса включено, обработчик прерывания ошибки UART подцепляется к цепочке обработчиков прерываний IVG. Когда детектировано событие изменения статуса линии (status event), приложение будет всякий раз оповещено через вызов callback-функции. Когда выключено оповещение о событиях изменения статуса линии, обработчик прерывания для UART отцепляется от цепочки IVG и запрещается проверка и оповещение событий изменения статуса линии. Value – TRUE включает оповещение об изменениях статуса линии и ошибках, FALSE выключает.
ADI_UART_CMD_SET_BAUD_RATE. Устанавливает скорость передачи данных (частота следования бит, baud rate) UART. Эта команда дает указание драйверу обновить регистры управления скоростью UART, основываясь на текущем значении тактовой частоты шины SCLK, чтобы установилась указанная скорость передачи. Value – u32, указанная скорости передачи в Герцах или бодах (baud rate).
ADI_UART_CMD_GET_TEMT. Команда позволяет приложению узнать значение бита TEMT. Эта команда используется, чтобы определить, когда пусты оба регистра TSR и THR. Обычно это используется, чтобы определить момент, когда все ожидающие передачи символы выдвинуты наружу, чтобы мог быть закрыт драйвер. Value – u32*, место в памяти, куда будет сохранено значение бита TEMT.
ADI_UART_CMD_AUTOBAUD. Задает автоматическое определение скорости (baud rate) на последовательном канале связи. Эта команда указывает драйверу UART автоматически детектировать по определенному принимаемому символу длительности бит фрейма, и по ним определять и автоматически настраивать скорость UART. Для сканирования и детектирования скорости UART драйвер ожидает поступления специального символа (autobaud character), по длительности бит которого и определяется скорость. Value – NULL.
ADI_UART_CMD_SET_AUTOBAUD_CHAR. Устанавливает символ для функции автоопределения скорости. Эта команда задает для драйвера эталонный символ (autobaud character), по которому определяется скорость UART. Value – u8 (символ ASCII).
ADI_UART_CMD_SET_DIVISOR_BITS. Альтернативный метод указания autobaud character. Эта команда задает значение бит делителя в автоматическом вычислении скорости. Может использоваться вместо команды ADI_UART_CMD_SET_AUTOBAUD_CHAR в случаях, когда указание определенного символа для автодетекта скорости может быть нежелательным. Value – u16 (количество бит).
ADI_UART_CMD_ENABLE_CTS_RTS. Разрешает или запрещает логику аппаратного управления потоком данных UART (flow control) с помощью сигналов CTS/RTS (CTS и RTS это специальные сигналы интерфейса RS-232). Внимание: эту команду поддерживают только те устройства UART, у которых есть поддержка аппаратного управления потоком CTS/RTS. Value – TRUE разрешает управление потоком сигналами CTS/RTS, FALSE запрещает управление сигналами CTS/RTS.
ADI_UART_CMD_SET_CTS_RTS_POLARITY. Устанавливает полярность активного уровня для сигналов CTS/RTS, т. е. какой логический уровень означает активность сигнала. По умолчанию у этих сигналов активным будет уровень лог. 0. Внимание: эту команду поддерживают только те устройства UART, у которых есть поддержка аппаратного управления потоком CTS/RTS. Value – TRUE устанавливает активную полярность для лог. 1, FALSE устанавливает активную полярность для лог. 0.
ADI_UART_CMD_SET_CTS_RTS_THRESHOLD. Устанавливает порог выставления CTS/RTS, либо низкий (когда заполнена половина FIFO) или высокий (FIFO полностью заполнен). По умолчанию установлен низкий порог. Внимание: эту команду поддерживают только те устройства UART, у которых есть поддержка аппаратного управления потоком CTS/RTS. Value – TRUE устанавливает высокий порог, FALSE устанавливает низкий порог.
ADI_UART_CMD_SET_TRANSFER_MODE. Разрешает работу в полудуплексе. Одно из направлений может быть запрещено, чтобы улучшить управление передачами данных UART. Внимание: эта команда допустима только в двунаправленном режиме потока данных. Value – 0 означает Full Duplex (Tx и Rx); 1 означает полудуплекс для передачи (только Tx); 2 означает полудуплекс для приема (только Rx); 3 запрещает и Tx, и Rx.
События callback. Ниже перечислены события для вызовов callback, которые может генерировать драйвер. События поделены на 2 врезки - общие события и события драйвера UART. Первая описывает события, которые являются общими для многих драйверов устройств. Другая секция описывает идентификаторы событий (event ID), специфичных именно для драйвера UART. Функция callback приложения должна быть подготовлена для обработки каждого из событий в этих врезках.
Callback-функция имеет тип ADI_DCB_CALLBACK_FN. В неё передается 3 параметра:
ClientHandle. Этот параметр имеет тип void*, его значение было передано драйверу устройства как параметр функции adi_dev_Open(). EventID. Это значение типа u32, которое указывает идентификатор события (event ID). Value. У этого параметра тип void*, и смысл этого значения зависит от контекста события (от специфического значения event ID).
Во врезках ниже перечислены идентификаторы event ID, которые может генерировать драйвер устройства, и значение параметра Value для каждого event ID.
Имеется только одно общее событие - ADI_DEV_EVENT_BUFFER_PROCESSED. Оно оповещает callback-функцию, что буфер был обработан драйвером устройства. Value – это значение параметра CallbackParameter, которое было предоставлено в буфере, который был передан в функцию API-функцию adi_dev_Read() или adi_dev_Write() Менеджера Устройств.
События, перечисленные ниже (event ID), поддерживаются и обрабатываются только драйвером UART. Значения этих event ID уникальны только для драйвера UART.
ADI_UART_EVENT_BREAK_INTERRUPT. Драйвер детектировал появление события break на линии. Чтобы это событие было детектировано, должно быть включено оповещение об изменениях статуса линии (line status event reporting). Value – NULL.
ADI_UART_EVENT_FRAMING_ERROR. Драйвер детектировал ошибку фрейма. Чтобы это событие было детектировано, должно быть включено оповещение об изменениях статуса линии (line status event reporting). Value – NULL.
ADI_UART_EVENT_PARITY_ERROR. Драйвер детектировал ошибку четности принятых данных. Чтобы это событие было детектировано, должно быть включено оповещение об изменениях статуса линии (line status event reporting). Value – NULL.
ADI_UART_EVENT_OVERRUN_ERROR. Драйвер детектировал ошибку переполнения приема. Чтобы это событие было детектировано, должно быть включено оповещение об изменениях статуса линии (line status event reporting). Value – NULL.
ADI_UART_EVENT_AUTOBAUD_COMPLETE. Завершена процедура автодетекта скорости. Value – u32, это значение параметра содержит детектированное значение скорости (baud rate).
[Коды возврата]
Все API-функции драйвера устройства возвращают статус, показывающий успешное выполнение функции или показывающий, какая произошла ошибка. Эта секция перечисляет коды возврата, которые драйвер UART может возвратить приложению. Значение возврата ADI_DEV_RESULT_SUCCESS показывает успешное завершение, в то время как другое значение показывает ошибку или какой-то другой информативный результат. ADI_DEV_RESULT_SUCCESS всегда соответствует нулевому значению кода возврата. Все другие коды возврата соответственно будут ненулевые.
Коды возврата бывают двух разновидностей, приведенных в отдельных врезках - общие коды возврата и коды возврата, специфические для драйвера UART. Первая врезка описывает коды возврата, которые возвращают многие драйверы, не только драйвер UART. Следующая врезка описывает коды возврата, относящиеся к драйверу UART. С какой бы ни было API-функцией драйвера приложение должно обработать все эти коды возврата.
Обычно приложение должно проверить код возврата на ADI_DEV_RESULT_SUCCESS, предпринимая соответствующие действия, когда код возврата не равен ADI_DEV_RESULT_SUCCESS. Например:
if (adi_dev_Xxxx(...) == ADI_DEV_RESULT_SUCCESS)
{
// Нормальная обработка, ошибки нет
...
}
Описанные здесь коды возврата API-функций драйвера являются общими для многих драйверов устройств. Список ниже перечисляет все общие коды возврата, поддерживаемые драйвером UART.
ADI_DEV_RESULT_SUCCESS. Выполнение функции было успешным.
ADI_DEV_RESULT_NOT_SUPPORTED. Эта функция не поддерживается драйвером.
ADI_DEV_RESULT_DEVICE_IN_USE. Запрошенное устройство уже используется.
ADI_DEV_RESULT_NO_MEMORY. Недостаточное количество доступной памяти.
ADI_DEV_RESULT_BAD_DEVICE_NUMBER. Недопустимый номер устройства.
ADI_DEV_RESULT_DIRECTION_NOT_SUPPORTED. Устройство не может быть открыто в заданном направлении.
ADI_DEV_RESULT_BAD_DEVICE_HANDLE. Недопустимый дескриптор для драйвера устройства.
ADI_DEV_RESULT_BAD_MANAGER_HANDLE. Недопустимый дескриптор для Менеджера Устройств.
ADI_DEV_RESULT_BAD_PDD_HANDLE. Недопустимый дескриптор для физического драйвера устройства.
ADI_DEV_RESULT_INVALID_SEQUENCE. Запрошенное действие не находится в допустимой последовательности.
ADI_DEV_RESULT_ATTEMPTED_READ_ON_OUTBOUND_DEVICE. Приложение сделало попытку предоставить входящий буфер для устройства, открытого только для исходящего трафика.
ADI_DEV_RESULT_ATTEMPTED_WRITE_ON_INBOUND_DEVICE. Приложение сделало попытку предоставить исходящий буфер для устройства, открытого только для входящего трафика.
ADI_DEV_RESULT_DATAFLOW_UNDEFINED. Еще не был декларирован метод поддержки потока данных.
ADI_DEV_RESULT_DATAFLOW_INCOMPATIBLE. Этот метод поддержки потока данных несовместим с запрошенным действием.
ADI_DEV_RESULT_BUFFER_TYPE_INCOMPATIBLE. Устройство не поддерживает этот тип предоставленного буфера.
ADI_DEV_RESULT_CANT_HOOK_INTERRUPT. Менеджер Прерываний [2] не смог подцепить обработчик прерывания.
ADI_DEV_RESULT_CANT_UNHOOK_INTERRUPT. Менеджер Прерываний [2] не смог отцепить обработчик прерывания.
ADI_DEV_RESULT_NON_TERMINATED_LIST. Предоставленная цепочка буферов не завершена NULL.
ADI_DEV_RESULT_NO_CALLBACK_FUNCTION_SUPPLIED. Потребовалась, но не была предоставлена callback-функция.
ADI_DEV_RESULT_REQUIRES_UNIDIRECTIONAL_DEVICE. Требуется, чтобы устройство было открыто только для одного направления трафика - либо только входящего, либо только для исходящего трафика.
ADI_DEV_RESULT_REQUIRES_BIDIRECTIONAL_DEVICE. Требуется, чтобы устройство было открыто только двунаправленного трафика - и входящего, и исходящего.
ADI_DEV_RESULT_DATAFLOW_NOT_ENABLED. В синхронном режиме буферы предоставлены перед разрешением потока данных.
ADI_DEV_RESULT_BAD_DIRECTION_FIELD. В режиме последовательного ввода/вывода буферы предоставлены с неправильным значением направления.
ADI_DEV_RESULT_BAD_IVG. Определен неправильный номер группы векторов (приоритетов) прерываний (IVG).
ADI_DEV_RESULT_ATTEMPTED_BUFFER_TABLE_NESTING. Вложенность таблицы буферов не дозволяется.
ADI_DEV_RESULT_DMA_CHANNEL_UNAVAILABLE. Не получилось предоставить буферы, потому что это устройство не имеет открытого канала DMA.
ADI_DEV_RESULT_SWITCH_BUFFER_PAIR_INVALID. Предоставлена недопустимая пара буферов с типом буфера переключение/обновление (Switch/Update).
Приведенные ниже коды возврата поддерживаются драйвером UART, они уникальны для этого драйвера.
ADI_UART_RESULT_TIMER_ERROR. Была детектирована ошибка при попытке управления и конфигурирования таймера для автоопределения скорости.
ADI_UART_RESULT_BAD_BAUD_RATE. Недопустимое значение baud rate. Эта ошибка возникает обычно когда клиент попытался разрешить поток данных перед тем, как функция автодетекта скорости определила и установила скорость.
ADI_UART_RESULT_NO_BUFFER. У драйвера нет буфера для обработки или определения счетчика обработанных элементов.
ADI_UART_RESULT_NOT_MAPPED_TO_DMA_CHANNEL. Драйвер не привязан к прерыванию канала DMA.
ADI_UART_RESULT_DMA_CHANNEL_NOT_MAPPED_TO_INTERRUPT. Драйвер DMA не привязан к прерыванию периферийного устройства UART.
[Открытие и конфигурирование драйвера UART]
В этом разделе описаны настройки конфигурации по умолчанию драйвера, и любые требуемые для приложения дополнительные настройки.
Точка входа. Когда драйвер устройства UART открывается вызовом функции adi_dev_Open(), клиент передает в эту функцию параметр, идентифицирующий определенный открываемый драйвер устройства. Этот параметр называется точкой входа (entry point). Для драйвера UART точку входа определяет глобальная переменная - структура ADIUARTDmaEntryPoint типа ADI_DEV_PDD_ENTRY_POINT, которая находится в исходном коде драйвера UART (Blackfin\lib\src\drivers\uart\adi_uart.c).
Настройки по умолчанию. В таблице 4 описаны настройки по умолчанию и их возможные значения для драйвера UART. Если настройки по умолчанию не подходят для имеющейся системы, клиент должен использовать соответствующие идентификаторы команд (command ID), чтобы правильно сконфигурировать драйвер UART. Настройки, не перечисленные в таблице, не определены по умолчанию, но это не означает, что их не надо определять. Например, к неопределенной по умолчанию настройке относится скорость бит UART.
Таблица 4. Настройки по умолчанию.
Опция
По умолчанию
Возможные значения
Command ID
Количество бит данных
5
5, 6, 7, 8
ADI_UART_CMD_SET_DATA_BITS
Количество стоп-битов
1
1, 1½, 2
ADI_UART_CMD_SET_STOP_BITS
Тип проверки на четность
Нечетность (odd)
FALSE: нечетность (odd), TRUE: четность (even)
ADI_UART_CMD_SET_PARITY
Разрешение проверки на четность
Запрещено
FALSE: запрещено, TRUE: разрешено
ADI_UART_CMD_ENABLE_PARITY
События для сообщения об изменении состояния линии
Запрещено
FALSE: запрещено, TRUE: разрешено
ADI_UART_CMD_SET_LINE_STATUS_EVENTS
Дополнительные необходимые настройки. В дополнение к тем настройкам, которые уже заданы по умолчанию (и которые можно переопределить соответствующими командами драйвера), есть также дополнительные настройки, которые должны быть установлены приложением. Эти настройки перечислены в таблице 5.
Таблица 5. Дополнительные требуемые настройки.
Опция
Возможные значения
Command ID
Метод потока данных
См. выше "Методы поддержки потока данных"
ADI_DEV_CMD_SET_DATAFLOW_METHOD
Скорость
Нужно указать скорость, или разрешить функцию autobaud
ADI_UART_CMD_SET_BAUD_RATE или ADI_UART_CMD_AUTOBAUD
[Работа с потоком данных]
Передача и прием данных осуществляются стандартным образом, как это делается для всех драйверов устройств (см. [3]) - с помощью предоставления буфера (буфер на прием предоставляется через adi_dev_Read, на передачу предоставляется через adi_dev_Write) и блокировки на семафоре. Блокировка на семафоре должна сниматься в коде callback, который привязан к предоставленному буферу. Поток, предоставляющий буфер периодически, должен блокироваться на этом семафоре и ожидать поступления данных в буфер приема (если поток обслуживает прием) или опустошения буфера передачи (если поток обслуживает передачу). Таким образом, для работы с драйвером UART как вариант целесообразно запустить два потока - один будет работать с буфером передачи, другой с буфером приема.