Программирование DSP Драйвер PPI для Blackfin Sun, November 10 2024  

Поделиться

Нашли опечатку?

Пожалуйста, сообщите об этом - просто выделите ошибочное слово или фразу и нажмите Shift Enter.


Драйвер PPI для Blackfin Печать
Добавил(а) microsin   

Интерфейс PPI процессора Blackfin [1] это полудуплексный, двунаправленный порт обмена параллельными данными. Он может передавать в любом направлении за одну операцию до 16 бит данных, и позволяет реализовать подключение к таким устройствам, как параллельные АЦП (ADC), ЦАП (DAC), кодировщики и декодеры видео.

Драйвер устройства PPI не работает напрямую под управлением прерываний, вместо этого используется служба прямого доступа к памяти (Direct Memory Access, DMA), которая в свою очередь использует прерывания.

Драйвер устройства PPI тестировался на платах разработчика (EZ-Kit Lite) ADSP-BF533, ADSP-BF561, и также на плате разработчика ADSP-BF537 EZ-Kit Lite с картой расширения для обработки звука/видео (A/V extender).

[Используемые файлы]

Все упомянутые здесь файлы находятся в поддиректориях каталога установки системы программирования 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/ppi/adi_ppi.h. Здесь содержатся коды всех команд, событий и значений возврата для API драйвера устройства PPI.

Исходный код. Исходный код драйвера PPI содержится в файле Blackfin/lib/src/drivers/ppi/adi_ppi.c. В этом модуле находится весь исходный код драйвера устройства PPI. Весь код написан на языке C. Для драйвера не используется никаких функций, написанных на ассемблере.

Код драйвера PPI не использует никакие низкоуровневые физические драйверы устройств, он сам фактически является таким драйвером.

[Ресурсы, требуемые для драйвера PPI]

Драйверы устройств обычно требуют для своей работы некоторое количество системных ресурсов (уровни приоритета прерываний IVG, каналы DMA, память). В этом разделе описаны ресурсы, которые требует для себя драйвер PPI.

За исключением специально указанных ниже случаев, этот драйвер использует Системные Службы для доступа к любой требуемой аппаратуре процессора и управления этой аппаратурой. Информация в этой секции может быть полезна в определении ресурсов, которые нужно выделить для драйвера PPI со стороны Системных Служб [4], наподобие количества обработчиков прерывания или количества используемых каналов DMA и т. п.

По той причине, что в Драйверах Устройств и Системных Службах [4] не используется динамическое выделение памяти, вся память для Драйверов Устройств и Системных Служб должна быть явно предоставлена приложением. Библиотека Драйверов Устройств и Системных Служб предоставляет специальные макросы, которые можно использовать в приложении для вычисления необходимого количества базовой памяти и/или количества дополнительной памяти, которая требуется для поддержки нужного функционала служб. Память для Менеджера Устройств и Системных Служб предоставляется специальными функциями инициализации соответствующего API (adi_ppi_Init()). Всякий раз, когда это возможно, драйвер PPI использует Системные Службы для выполнения необходимого низкоуровневого доступа к аппаратуре процессора.

Прерывания. Для каждого открытия драйвера PPI используется только одно прерывание для обработки ошибки PPI.

За исключением случаев, когда это отменено соответствующими командами SetIVG, драйвер PPI использует привязку групп прерываний IVG и их настройку по умолчанию (т. е. используется настройка привязки по умолчанию для процессора, которая действует после сброса / включения питания).

Драйвер устройства PPI подключает или отключает обработчик прерывания ошибки, когда клиент вызывает функцию adi_dev_Control() с командой ADI_DEV_CMD_SET_ERROR_REPORTING. Если с командой передан аргумент TRUE, то прерывание ошибки разрешается, и обработчик прерывания ошибки подцепляется в цепочку IVG. Если с командой передан аргумент FALSE, то прерывание запрещается, и обработчик прерывания отцепляется от цепочки IVG. Когда клиент закрывает драйвер вызовом adi_dev_close(), то прерывание ошибки, если оно разрешено и подцеплено, автоматически запрещается и отцепляется [3].

DMA. Драйвер PPI используется совместно со службой DMA. Один канал DMA должен быть выделен для каждого открытия драйвера PPI. Если процессор использует два порта PPI, и они используются одновременно (возможно один для ввода, другой для вывода), то должны быть выделены и инициализированы два канала DMA. В случае двухядерного процессора каждое ядро может использовать отдельное устройство PPI и канал DMA, позволяя одному ядру обрабатывать ввод, а другому ядру обрабатывать вывод.

Таймер. Драйвер PPI использует службу управления таймерами (Timer Control service [2]) для доступа к ресурсам таймеров с целью формирования синхроимпульсов кадра (frame sync). Когда используется frame sync 1 или frame sync 2, клиент вызывает функцию adi_dev_Control() с командой ADI_PPI_CMD_SET_TIMER_FRAME_SYNC_1 или ADI_PPI_CMD_SET_TIMER_FRAME_SYNC_2 вместе с указателем на конфигурационную структуру ADI_PPI_FS_TMR, которая содержит следующие поля:

pulse - уровень импульса, 0 показывает активный импульс лог. 0, и 1 показывает импульс лог. 1.
emu_run - флаг, который указывает, должен ли таймер работать, когда процессор остановлен (с помощью отладчика JTAG). Значение 1 указывает, что таймер продолжит работать, 0 указывает, что таймер должен при остановке процессора тоже останавливаться.
period - период импульса (количество тактов PPI_CLK между началами импульсов).
width - ширина импульса (количество тактов PPI_CLK в течение активного уровня каждого импульса).
enable_delay – количество тактов PPI CLK на которое сигнал синхронизации должен быть задержан перед тем, как он может быть разрешен. Если нет требований к задержке, то это поле должно быть установлено в 0.

Когда требуется 3 сигнала синхроимпульса кадра (frame sync), клиент вызывает функцию adi_pdd_Control() с аргументом ADI_PPI_CMD_SET_TRIPLE_FRAME_SYNC, что приводит к установке флага TripleFrameSyncFlag.

Часы реального времени (RTC). Драйвер устройства PPI не использует какие-либо службы часов реального времени.

Программируемые флаги. У драйвера PPI есть выделенные ножки для тактов, трех синхроимпульсов кадра (frame sync) и 8 выводов данных. На процессорах, где используется мультиплексирование выводов (например [1]), 8 выводов программируемых флагов (PF) могут быть переконфигурированы для предоставления 8 дополнительных выводов данных PPI, что дает суммарно поддержку 16-битных данных. Ножка тактов (PPIx_CLK) не является источником сигналов тактов, она может только принимать внешний тактовый сигнал (это вход).

[Функции, поддерживаемые драйвером PPI]

Направление потоков данных. Драйвер поддерживает приведенные в таблице ниже варианты настройки для направления потока данных. ADI_DEV_DIRECTION это тип перечисления enum, задающий варианты направления данных (определен в заголовочном файле Blackfin\include\drivers\adi_dev.h).

ADI_DEV_DIRECTION Описание
ADI_DEV_DIRECTION_INBOUND Поддерживает прием данных в устройство.
ADI_DEV_DIRECTION_OUTBOUND Поддерживает передачу данных из устройства.

Методы потока данных. Поддерживаемые методы организации потока данных перечислены в таблице ниже. ADI_DEV_MODE это тип перечисления enum, задающий варианты предоставления буферов для данных (определен в заголовочном файле Blackfin\include\drivers\adi_dev.h).

ADI_DEV_MODE Описание
ADI_DEV_MODE_CIRCULAR Метод кольцевого буфера.
ADI_DEV_MODE_CHAINED Метод цепочек буферов.
ADI_DEV_MODE_CHAINED_LOOPBACK Метод цепочек буферов с переходом на начало цепочки.

Типы буфера. Эта версия драйвера поддерживает следующие типы буфера (в поле pAdditionalInfo передаются дополнительные опции):

ADI_DEV_CIRCULAR_BUFFER. Кольцевой буфер.
ADI_DEV_1D_BUFFER. Одномерный буфер.
ADI_DEV_2D_BUFFER. Двумерный буфер.

Идентификаторы команд. В этой секции перечислены команды, поддерживаемые драйвером. Команды делятся на 3 секции. Первая описывает команды, поддерживаемые напрямую Менеджером Устройств. Следующая секция описывает общие поддерживаемые драйвером команды (относящиеся ко всем драйверам, не только к PPI). Последняя секция описывает специфические для драйвера PPI команды.

Команды посылаются в драйвер устройства через функцию 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), которые поддерживаются драйвером PPI.

ADI_DEV_CMD_GET_2D_SUPPORT. Позволяет вызывающему коду определить, может ли драйвер поддерживать двумерные (2D) буферы. Value – u32*, указывает на ячейку, куда помещается ответ (TRUE/FALSE).

ADI_DEV_CMD_SET_DATAFLOW_METHOD. Задает используемый метод потока данных устройства. Value – одно из поддерживаемых значений перечисления ADI_DEV_MODE (см. таблицу выше).

ADI_DEV_CMD_SET_STREAMING. Разрешает / запрещает потоковый режим драйвера. Value – TRUE/FALSE.

ADI_DEV_CMD_GET_INBOUND_DMA_CHANNEL_ID. Вернет ID канала DMA драйвера для входящего DMA. Value – u32* (ячейка, куда сохраняется ID канала).

ADI_DEV_CMD_GET_OUTBOUND_DMA_CHANNEL_ID. Вернет ID канала DMA драйвера для исходящего DMA. Value – u32* (ячейка, куда сохраняется ID канала).

ADI_DEV_CMD_SET_INBOUND_DMA_CHANNEL_ID. Установит ID канала DMA драйвера для входящего DMA. Value – ADI_DMA_CHANNEL_ID (ID канала DMA).

ADI_DEV_CMD_SET_OUTBOUND_DMA_CHANNEL_ID. Установит ID канала DMA драйвера для исходящего DMA. Value – ADI_DMA_CHANNEL_ID (ID канала DMA).

ADI_DEV_CMD_GET_INBOUND_DMA_PMAP_ID. Вернет PMAP ID драйвера для входящего канала DMA. Value – u32* (ячейка, куда будет сохранено значение PMAP).

ADI_DEV_CMD_GET_OUTBOUND_DMA_PMAP_ID. Вернет PMAP ID драйвера для исходящего канала DMA. Value – u32* (ячейка, куда будет сохранено значение PMAP).

ADI_DEV_CMD_SET_DATAFLOW. Разрешает/запрещает поток данных через устройство. Value – TRUE/FALSE.

ADI_DEV_CMD_GET_PERIPHERAL_DMA_SUPPORT. Позволяет вызывающему коду определить, поддерживается ли драйвер периферийным DMA. Value – u32*, указывает на ячейку, куда помещается ответ (TRUE/FALSE).

ADI_DEV_CMD_SET_ERROR_REPORTING. Разрешает/запрещает сообщения от ошибках со стороны драйвера устройства. Value – TRUE/FALSE.

ADI_DEV_CMD_GET_MAX_INBOUND_SIZE. Вернет максимальное количество байт данных для входящего буфера. Value – u32* (ячейка, куда будет сохранен размер буфера).

ADI_DEV_CMD_GET_MAX_OUTBOUND_SIZE. Вернет максимальное количество байт данных для исходящего буфера. Value – u32* (ячейка, куда будет сохранен размер буфера).

ADI_DEV_CMD_FREQUENCY_CHANGE_PROLOG. Оповещает драйвер устройства немедленно перед изменением частоты CCLK/SCLK. Value – ADI_DEV_FREQUENCIES* (новые частоты).

ADI_DEV_CMD_FREQUENCY_CHANGE_EPILOG. Оповещает драйвер устройства немедленно после изменения частоты CCLK/SCLK. Value – ADI_DEV_FREQUENCIES* (новые частоты).

ADI_DEV_CMD_8BIT_BLOCK_READ. Читает блок 8-битных регистров из устройства. Value – ADI_DEV_8BIT_BLOCK* (специфические регистры).

ADI_DEV_CMD_8BIT_BLOCK_WRITE. Записывает блок 8-битных регистров в устройстве. Value – ADI_DEV_8BIT_BLOCK* (специфические регистры).

ADI_DEV_CMD_8BIT_BLOCK_READ_FIELD. Читает определенные поля в блоке 8-битных регистров устройства. Value – ADI_DEV_8BIT_BLOCK_FIELD* (регистр и его специфические поля).

ADI_DEV_CMD_8BIT_BLOCK_WRITE_FIELD. Записывает определенные поля в блоке 8-битных регистров устройства. Value – ADI_DEV_8BIT_BLOCK_FIELD* (регистр и его специфические поля).

ADI_DEV_CMD_8BIT_SELECTIVE_READ. Читает определенный набор 8-битных регистров устройства. Value – ADI_DEV_8BIT_SELECTIVE* (специфические регистры).

ADI_DEV_CMD_8BIT_SELECTIVE_WRITE. Записывает определенный набор 8-битных регистров устройства. Value – ADI_DEV_8BIT_SELECTIVE* (специфические регистры).

ADI_DEV_CMD_8BIT_SELECTIVE_READ_FIELD. Читает определенные поля из выбранного набора 8-битных регистров устройства. Value – ADI_DEV_8BIT_SELECTIVE_FIELD* (специфические особенности регистров).

ADI_DEV_CMD_8BIT_SELECTIVE_WRITE_FIELD. Записывает определенные поля выбранного набора 8-битных регистров устройства. Value – ADI_DEV_8BIT_SELECTIVE_FIELD* (специфические особенности регистров).

Идентификаторы команд, перечисленные ниже, поддерживаются и обрабатываются драйвером PPI, они уникальны именно для этого драйвера устройства.

ADI_PPI_CMD_SET_CONTROL_REG. Устанавливает регистр управления PPI. Value – ADI_PPI_CONTROL_REG.

ADI_PPI_CMD_SET_DELAY_COUNT_REG. Устанавливает счетчик задержки PPI. Value – u16.

ADI_PPI_CMD_SET_TRANSFER_COUNT_REG. Устанавливает счетчик транзакций PPI. Value – u16.

ADI_PPI_CMD_SET_LINES_PER_FRAME_REG. Устанавливает количество строк в кадре. Value – u16.

ADI_PPI_CMD_SET_FS_INVERT. Инвертирует полярность frame sync путем установки 1-разрядного поля в структуре регистра управления. Value = TRUE/FALSE, TRUE = инверсия, FALSE = без инверсии.

ADI_PPI_CMD_SET_CLK_INVERT. Инвертирует полярность синхроимпульсов кадра (frame sync) и тактов (PPI clock) путем установки 1-разрядного поля в структуре регистра управления. Value = TRUE/FALSE, TRUE = инверсия, FALSE = без инверсии.

ADI_PPI_CMD_SET_DATA_LENGTH. Устанавливает длину данных путем установки 3-битного поля в структуре регистра управления. Value – u16.

ADI_PPI_CMD_SET_SKIP_EVEN_ODD. Пропускает четные элементы путем установки 1-разрядного поля в структуре регистра управления. Value u16, 1 = пропуск четных элементов, 0 = пропуск нечетных.

ADI_PPI_CMD_SET_SKIP_ENABLE. Управляет пропуском элементов. Value = u16, 1 = разрешить пропуск, 0 = запретить.

ADI_PPI_CMD_SET_PACK_ENABLE. Разрешает/запрещает упаковку данных путем установки 3-битного поля в структуре регистра управления. Value = u16, 0 = запрет упаковки, 1 = разрешает упаковку в режиме ввода, и распаковку в режиме вывода.

ADI_PPI_CMD_SET_ACTIVE_FIELD_SELECT. Выбирает активные поля. Value = type u16. В режиме ITU-R 656, когда xfr_type = 00, 0 = Field 1, 1 = Field 1 и Field 2. В RX-режиме с внешними frame sync, когда port_cfg = 11, 0 = external trigger, 1 = internal trigger.

ADI_PPI_CMD_SET_PORT_CFG. Устанавливает конфигурацию порта путем установки 2-разрядного поля в структуре ADI_PPI_CONTROL_REG. В не-ITU-R 656 режимах ввода (PORT_DIR=0, XFR_TYPE=11): 00 = 1 внешний frame sync, 01 = 2 или 3 внутренних frame sync, 10 = 2 или 3 внешних frame sync, 11 = без frame sync. В режимах вывода с frame sync (PORT_DIR=0, XFR_TYPE=11): 00= 1 frame sync, 01 = 2 или 3 frame sync, 10 – зарезервировано, 11 – Sync PPI_FS3 для установки PPI_FS2 вместо установки PPI_FS1.

ADI_PPI_CMD_SET_TRANSFER_TYPE. Выбирает тип транзакции путем установки 2-разрядного поля структуры ADI_PPI_CONTROL_REG. Value = битовое поле u16, 0 = ITU-R 656 active field only, no frame sync, 1 = ITU-R 656 entire field, без frame sync, 2 = ITU-R 656 vertical blanking only, без frame sync, 3 = non-ITU-R 656 и port_cfg определяет frame sync.

ADI_PPI_CMD_SET_PORT_DIRECTION. Устанавливает направление порта установкой 1-разрядного поля структуры ADI_PPI_CONTROL_REG. Value = TRUE для вывода, FALSE для ввода.

ADI_PPI_CMD_SET_TRIPLE_FRAME_SYNC. Установит флаг тройной синхронизации кадра (triple frame sync). Value = TRUE для установки флага, FALSE для очистки флага.

ADI_PPI_CMD_SET_TIMER_FRAME_SYNC_1. Установит таймер для frame sync 1 (PPI_FS1). Value = ADI_PPI_FS_TMR*.

ADI_PPI_CMD_SET_TIMER_FRAME_SYNC_2. Установит таймер для frame sync 2 (PPI_FS2). Value = ADI_PPI_FS_TMR*.

События callback. Ниже перечислены события для вызовов callback, которые может генерировать драйвер. События поделены на 2 врезки - общие события и события драйвера PPI. Первая описывает события, которые являются общими для многих драйверов устройств. Другая секция описывает идентификаторы событий (event ID), специфичных именно для драйвера PPI. Функция callback приложения должна быть подготовлена для обработки каждого из событий в этих врезках.

Callback-функция имеет тип ADI_DCB_CALLBACK_FN [6]. В неё передается 3 параметра:

ClientHandle. Этот параметр имеет тип void*, его значение было передано драйверу устройства как параметр функции adi_dev_Open().
EventID. Это значение типа u32, которое указывает идентификатор события (event ID).
Value. У этого параметра тип void*, и смысл этого значения зависит от контекста события (от специфического значения event ID).

Во врезках ниже перечислены идентификаторы event ID, которые может генерировать драйвер устройства, и значение параметра Value для каждого event ID.

Здесь описаны события, которые общие для многих драйверов устройств. Список ниже перечисляет все ID общих событий, поддерживаемых драйвером устройства PPI.

ADI_DEV_EVENT_BUFFER_PROCESSED. Оповещает callback-функцию, что цепочечный (chained) или последовательный (sequential I/O) буфер был обработан драйвером устройства. Это событие также используется для оповещения, что весь кольцевой буфер было обработан, если драйверу было указано генерировать вызов callback по завершению обработки всего кольцевого буфера. Value – для методов потока данных chained или sequential I/O это значение будет равно значению CallbackParameter, которое было предоставлено в буфере, переданным в функцию adi_dev_Read(), adi_dev_Write() или adi_dev_SequentialIO(). Для метода кольцевого потока данных это значение является адресом буфера, переданного в функцию adi_dev_Read() или adi_dev_Write().

ADI_DEV_EVENT_SUB_BUFFER_PROCESSED. Оповещает callback-функцию, что драйвером устройства был обработан sub-буфер в кольцевом буфере. Value – адрес буфера, переданного в функцию adi_dev_Read() или adi_dev_Write().

ADI_DEV_EVENT_DMA_ERROR_INTERRUPT. Оповещает callback-функцию, что произошла ошибка DMA. Value – NULL.

Драйвером устройства PPI поддерживается только одно событие, предназначенное только для этого драйвера:

ADI_PPI_EVENT_ERROR_INTERRUPT. Это событие означает, что драйвер определил ошибку PPI. Value – NULL.

[Коды возврата]

Все API-функции драйвера устройства возвращают статус, показывающий успешное выполнение функции или показывающий, какая произошла ошибка. Эта секция перечисляет коды возврата, которые драйвер PPI может возвратить приложению. Значение возврата ADI_DEV_RESULT_SUCCESS показывает успешное завершение, в то время как другое значение показывает ошибку или какой-то другой информативный результат. ADI_DEV_RESULT_SUCCESS всегда соответствует нулевому значению кода возврата. Все другие коды возврата соответственно будут ненулевые.

Коды возврата бывают двух разновидностей, приведенных в отдельных врезках - общие коды возврата и коды возврата, специфические для драйвера PPI. Первая врезка описывает коды возврата, которые возвращают многие драйверы, не только драйвер PPI. Следующая врезка описывает коды возврата, относящиеся к драйверу PPI. С какой бы ни было API-функцией драйвера приложение должно обработать все эти коды возврата.

Обычно приложение должно проверить код возврата на ADI_DEV_RESULT_SUCCESS, предпринимая соответствующие действия, когда код возврата не равен ADI_DEV_RESULT_SUCCESS. Например:

if (adi_dev_Xxxx(...) == ADI_DEV_RESULT_SUCCESS)
{
   // Нормальная обработка, ошибки нет
   ...
}
else
{
   // Обработка ошибки
   ...
} 

Описанные здесь коды возврата API-функций драйвера являются общими для многих драйверов устройств. Список ниже перечисляет все общие коды возврата, поддерживаемые драйвером PPI.

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. Менеджер Прерываний [3] не смог подцепить обработчик прерывания.

ADI_DEV_RESULT_CANT_UNHOOK_INTERRUPT. Менеджер Прерываний [3] не смог отцепить обработчик прерывания.

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. Требуется, чтобы устройство было открыто только двунаправленного трафика - и входящего, и исходящего.

Приведенные ниже коды возврата поддерживаются драйвером PPI, они уникальны для этого драйвера.

ADI_PPI_RESULT_TIMER_ERROR. Была определена ошибка при попытке управления и конфигурирования таймера для frame sync.

[Открытие и конфигурирование драйвера PPI]

В этом разделе описаны настройки конфигурации по умолчанию драйвера, и любые требуемые для приложения дополнительные настройки.

Точка входа. Когда драйвер устройства PPI открывается вызовом функции adi_dev_Open(), клиент передает в эту функцию параметр, идентифицирующий определенный открываемый драйвер устройства. Этот параметр называется точкой входа (entry point). Для драйвера PPI точку входа определяет глобальная переменная - структура ADIPPIEntryPoint типа ADI_DEV_PDD_ENTRY_POINT, которая находится в исходном коде драйвера PPI (Blackfin\lib\src\drivers\ppi\adi_ppi.c).

ADI_DEV_PDD_ENTRY_POINT ADIPPIEntryPoint =
{
   adi_pdd_Open,
   adi_pdd_Close,
   adi_pdd_Read,
   adi_pdd_Write,
   adi_pdd_Control
};

Настройки по умолчанию. В таблице ниже описаны настройки по умолчанию и их возможные значения для драйвера PPI. Если настройки по умолчанию не подходят для имеющейся системы, клиент должен использовать соответствующие идентификаторы команд (command ID), чтобы правильно сконфигурировать драйвер PPI. Настройки, не перечисленные в таблице, не определены по умолчанию, но это не означает, что их можно не определять.

Опция По умолч. Возможные значения Command ID
Регистр управления (PPI_CONTROL) 0 См. описание полей регистра в [1] ADI_PPI_CMD_SET_CONTROL_REG
Разрешение порта 0 0 порт запрещен, 1 разрешен ADI_DEV_CMD_SET_DATAFLOW
Направление 0 0 ввод, 1 вывод ADI_PPI_CMD_SET_PORT_DIRECTION
Тип транзакции 0 0,1,2,3 (см. описание команды) ADI_PPI_CMD_SET_TRANSFER_TYPE
Конфигурация порта 0 0,1,2,3 (см. описание команды) ADI_PPI_CMD_SET_PORT_CFG
Активное поле 0 0,1 (см. описание команды) ADI_PPI_CMD_SET_ACTIVE_FIELD_SELECT
Упаковка 0 0 запрещено, 1 разрешено ADI_PPI_CMD_SET_PACK_ENABLE
32-bit DMA 0 0 запрещено, 1 разрешено ADI_PPI_CMD_SET_CONTROL_REG
Счетчик транзакций 0 0 - 65535 ADI_PPI_CMD_SET_TRANSFER_COUNT_REG
Регистр счетчика задержки 0 0 - 65535 ADI_PPI_CMD_SET_DELAY_COUNT_REG
Строк на кадр 0 0 - 65535 ADI_PPI_CMD_SET_LINES_PER_FRAME_REG
Тройная синхронизация кадра FALSE TRUE/FALSE ADI_PPI_CMD_SET_TRIPLE_FRAME_SYNC
Таймер для FS1 FALSE TRUE/FALSE ADI_PPI_CMD_SET_TIMER_FRAME_SYNC_1
Таймер для FS2 FALSE TRUE/FALSE ADI_PPI_CMD_SET_TIMER_FRAME_SYNC_2
Длина данных 0 0-7 (от 8 до 16 бит) ADI_PPI_CMD_SET_DATA_LENGTH
Пропуск четных или нечетных слов 0 0 пропуск нечетных, 1 четных ADI_PPI_CMD_SET_SKIP_EVEN_ODD
Разрешение пропуска 0 0 запрещено, 1 разрешено ADI_PPI_CMD_SET_SKIP_ENABLE
Инверсия тактов 0 0 без инверсии, 1 инверсия ADI_PPI_CMD_SET_CLK_INVERT
Инверсия синхроимпульсов кадра 0 0 без инверсии, 1 инверсия ADI_PPI_CMD_SET_FS_INVERT

Дополнительные необходимые настройки. В дополнение к тем настройкам, которые уже заданы по умолчанию (и которые можно переопределить соответствующими командами драйвера), есть также дополнительные настройки, которые должны быть установлены приложением. Эти настройки перечислены в таблице ниже.

Опция Возможные значения Command ID
Регистр управления (PPI_CONTROL) См. описание полей регистра в [1] ADI_PPI_CMD_SET_CONTROL_REG
Запуск потока данных (разрешение PPI) 0 запрещено, 1 разрешено ADI_DEV_CMD_SET_DATAFLOW
Счетчик задержки 0 - 65535 ADI_PPI_CMD_SET_DELAY_COUNT_REG
Счетчик транзакций 0 - 65535 ADI_PPI_CMD_SET_TRANSFER_COUNT_REG
Строк на кадр 0 - 65535 ADI_PPI_CMD_SET_LINES_PER_FRAME_REG
Полярность синхроимпульсов кадра 0 без инверсии, 1 инверсия ADI_PPI_CMD_SET_FS_INVERT
Инверсия тактов 0 без инверсии, 1 инверсия ADI_PPI_CMD_SET_CLK_INVERT
Длина данных 0-7 (от 8 до 16 бит) ADI_PPI_CMD_SET_DATA_LENGTH
Пропуск четных или нечетных слов 0 пропуск нечетных, 1 четных ADI_PPI_CMD_SET_SKIP_EVEN_ODD
Разрешение пропуска 0 запрещено, 1 разрешено ADI_PPI_CMD_SET_SKIP_ENABLE
Разрешение упаковки 0 запрещено, 1 разрешено ADI_PPI_CMD_SET_PACK_ENABLE
Выбор активного поля TRUE/FALSE ADI_PPI_CMD_SET_ACTIVE_FIELD_SELECT
Конфигурация порта 0 - 3 ADI_PPI_CMD_SET_PORT_CFG
Выбор типа транзакции 0 - 3 ADI_PPI_CMD_SET_TRANSFER_TYPE
Выбор направления работы порта 0 ввод, 1 вывод ADI_PPI_CMD_SET_PORT_DIRECTION
Тройная синхронизация кадра TRUE/FALSE ADI_PPI_CMD_SET_TRIPLE_FRAME_SYNC
Таймер для FS1 TRUE/FALSE ADI_PPI_CMD_SET_TIMER_FRAME_SYNC_1
Таймер для FS2 TRUE/FALSE ADI_PPI_CMD_SET_TIMER_FRAME_SYNC_2

[Особенности аппаратуры]

Обратите внимание, что когда используются синхроимпульс кадра (frame sync), то применяется предварительно определенный процессором таймер общего назначения, в зависимости от желаемого количества синхроимпульсов frame sync. Какой специфический Timer ID используется, можно посмотреть в определении структуры Device, в файле adi_ppi.c.

Некоторые процессоры позволяют мультиплексировать входные и выходные выводы данных с программируемыми флагами (PF), так что PPI может быть сконфигурирован как для данных шириной 8 бит, или могут быть задействованы 8 выводов PF для организации 16-битной шины данных. Пользователь должен с осторожностью использовать выводы PPI, чтобы это не мешало другим устройствам.

[Ссылки]

1. ADSP-BF538 PPI.
2VDK: служба таймеров.
3VDK: менеджер прерываний.
4VDK: драйверы устройств и системные службы процессоров Blackfin.
5VDK: менеджер драйверов устройств.
6VDK: менеджер отложенных функций обратного вызова.

 

Добавить комментарий


Защитный код
Обновить

Top of Page