Программирование DSP Программный драйвер I2C/TWI для Blackfin Mon, April 22 2019  

Поделиться

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

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


Программный драйвер I2C/TWI для Blackfin Печать
Добавил(а) microsin   

Драйвер TWI, разработанный Analog Devices, может работать в аппаратном и программном режиме. Здесь описан только программный драйвер pseudo TWI (перевод документации adi_twi_pseudo.pdf). Для информации по аппаратному драйверу TWI см. документ adi_twi.pdf (или статью [4]). Программный драйвер поддерживает только режим мастера, и при попытке конфигурирования в режим подчиненного устройства (с помощью команды ADI_DEV_CMD_SET_DATAFLOW) будет возвращена ошибка. Pseudo TWI может работать вместе с n других устройств pseudo TWI и/или аппаратными устройствами TWI (количество ограничивается только аппаратурой). Обратите внимание, что аппаратные ресурсы, выделенные для каждого pseudo TWI, не могут быть использованы где-либо еще, когда включен поток данных на этом устройстве (DATAFLOW on).

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

Все упомянутые здесь файлы находятся в поддиректориях каталога установки системы программирования VisualDSP++. Указанные пути для подключаемых файлов начинаются с директории %ProgramFiles%\Analog Devices\VisualDSP 5.0\Blackfin\include, а для файлов исходного кода с директории %ProgramFiles%\Analog Devices\VisualDSP 5.0\Blackfin\lib\src.

Подключаемые файлы. Исходный код драйвера подключает следующие заголовочные файлы:

services/services.h. Здесь содержатся все определения, прототипы функций и т. д. для всей библиотеки Системных Служб (System Services Library, SSL).

drivers/adi_dev.h. Здесь содержатся все определения, прототипы функций и т. д. для Менеджера Устройств (Device Manager) и общая информация по модели Драйвера Устройства.

drivers/twi/adi_twi.h. Здесь содержатся коды всех команд, событий и значений возврата, прототипы функций для API драйвера устройства TWI.

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

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

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

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

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

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

Прерывания. Этот драйвер TWI использует прерывание таймера, и если работает master arbitration mode, то используется одно прерывание флага.

DMA. Этот драйвер TWI не использует прямой доступ к памяти.

Таймер. Этот драйвер TWI использует одно прерывание таймера, которое выбирается с помощью структуры adi_twi_pseudo_port, которая передается в команду ADI_TWI_CMD_SET_PSEUDO.

RTC. Этот драйвер TWI не использует часы реального времени.

Программируемые флаги. Этот драйвер использует два программируемых флага (т. е. ножки GPIO процессора), которые определены в структуре adi_twi_pseudo_port, переданной в команду ADI_TWI_CMD_SET_PSEUDO. Если используется master arbitration, то флаг SCL также использует callback-функцию.

Используемые выводы. Интерфейс TWI для соединения с внешним миром использует 2 сигнальных провода - SCL и SDA. Этот драйвер использует для этой цели 2 вывода GPIO, которые можно сконфигурировать командой ADI_TWI_CMD_SET_PSEUDO. Они могут меняться в зависимости от используемого процессора Blackfin.

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

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

Таблица 2. Поддерживаемые направления потока данных (Dataflow Directions).

ADI_DEV_DIRECTION Описание
ADI_DEV_DIRECTION_BIDIRECTIONAL Поддерживает двунаправленный поток данных с устройством (прим и передача данных).

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

Таблица 3. Поддерживаемые методы организации потока данных.

ADI_DEV_MODE Описание
ADI_DEV_MODE_SEQ_CHAINED Поддерживает последовательный поток данных ввода/вывода (цепочки буферов). Этот метод переводит устройство TWI в режим главного (мастер шины, master I2C).

Типы буфера. Эта версия драйвера поддерживает только один тип буфера:

ADI_DEV_SEQ_1D_BUFFER. Это линейная одномерная цепочка буферов. Поле pAdditionalInfo имеет тип u32, оно используется (для передачи значения адреса в подчиненного устройства, или макроса ADI_TWI_REPEAT_START.

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

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

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

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

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

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

ADI_TWI_CMD_SET_HARDWARE. Устанавливает, какой из аппаратных интерфейсов TWI будет использоваться драйвером. Value - ADI_INT_PERIPHERAL_ID (id прерывания аппаратуры TWI). В ответ на эту команду программный драйвер TWI вернет ошибку.

ADI_TWI_CMD_SET_PSEUDO. Устанавливает TWI в псевдо-режим (программная реализация TWI). Value - структура adi_twi_pseudo_port * (структура псевдо-порта, определенная в adi_twi.h).

ADI_TWI_CMD_SET_RATE. Установит частоту порта TWI. Value - указатель на структуру adi_twi_bit_rate (структура определена в adi_twi.h, она содержит частоту и скважность).

ADI_TWI_CMD_SET_SLAVE_ADDR. Установит адрес подчиненного устройства, когда драйвер работает в slave mode. Value - u32 (здесь находится 7-разрядное значение адреса подчиненного устройства). В ответ на эту команду программный драйвер TWI вернет ошибку.

ADI_TWI_CMD_SET_GCAL. Разрешает общую адресацию (general call addressing) в slave mode. Value не используется.

ADI_TWI_CMD_SET_SCCB. Разрешает SCCB-совместимость в master mode. Value не используется. SCCB это сокращение от Serial Camera Control Bus, шина для подключения видеокамер фирмы OmniVision.

ADI_TWI_CMD_SET_SCLOVR. Отменяет флаг SCL, когда установка выхода на выводе SCL будет выдавать лог. 0. Value - TRUE/FALSE.

ADI_TWI_CMD_SET_SDAOVR. Отменяет флаг SDA, когда установка выхода на выводе SDA будет выдавать лог. 0. Value - TRUE/FALSE.

ADI_TWI_CMD_SET_FIFO. Установит для буфера режим работы FIFO. Value - u32 (0x0008 разрешает прием прерывания на границе слова, 0x0004 разрешает прерывания при передаче слова, драйвер автоматически обрабатывает нечетные передачи байта).

ADI_TWI_CMD_SET_LOSTARB. Устанавливает количество повторных попыток для событий потери арбитража перед запуском callback-функции. Value - u32 (0 никогда не генерировать вызов callback, иначе значение показывает количество событий потери арбитража, после чего будет запущена функция callback).

ADI_TWI_CMD_SET_ANAK. Установит количество повторных попыток адресации при событиях отрицательного подтверждения (NACK), после которых будет запущен callback. Value - u32 (0 никогда не генерировать вызов callback, иначе значение показывает количество событий NACK, после чего будет запущена функция callback).

ADI_TWI_CMD_SET_DNAK. Установит количество повторных попыток перемещения данных при событиях отрицательного подтверждения (NACK), после которых будет запущен callback. Value - u32 (0 никогда не генерировать вызов callback, иначе значение показывает количество событий NACK, после чего будет запущена функция callback).

ADI_TWI_CMD_GET_SENSE. Получит состояние флагов SDA, SCL и BUSBUSY. Value - u32 * (адрес ячейки, где хранятся биты остояния: 0x0100=BUSBUSY, 0x0080=SCL и 0x0040=SDA).

События callback. Ниже перечислены события для вызовов callback (функция обратного вызова), когда они разрешены для генерации драйвером. События поделены на 2 врезки - общие события и события драйвера TWI. Первая описывает события, которые являются общими для многих драйверов устройств. Другая секция описывает идентификаторы событий (event ID), специфичных именно для драйвера TWI. Функция 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.

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

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

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

[События master mode]

ADI_TWI_EVENT_BUFWRERR. Переполнение буфера приема, обычно это событие показывает, что больше нет предоставленных для приема буферов. Value - значение CallbackParameter, предоставленное в буфере, который был передан в функцию adi_dev_SequentialIO().

ADI_TWI_EVENT_BUFRDERR. Недогрузка буфера передачи, обычно это событие показывает, что больше не было предоставлено доступных буферов передачи. Value - значение CallbackParameter, предоставленное в буфере, который был передан в функцию adi_dev_SequentialIO().

ADI_TWI_EVENT_DNAK. Получен x раз сигнал отрицательного подтверждения данных (Data Negative Acknowledge, DNACK), где x это значение, установленное командой ADI_TWI_CMD_SET_DNAK. Value - значение CallbackParameter, предоставленное в буфере, который был передан в функцию adi_dev_SequentialIO().

ADI_TWI_EVENT_ANAK. Получен x раз сигнал отрицательного подтверждения адреса (Address Negative Acknowledge, ANACK), где x это значение, установленное командой ADI_TWI_CMD_SET_ANAK. Value - значение CallbackParameter, предоставленное в буфере, который был передан в функцию adi_dev_SequentialIO().

ADI_TWI_EVENT_LOSTARB. TWI потерял арбитраж x раз, здесь x это значение, установленное командой ADI_TWI_CMD_SET_LOSTARB. Value - значение CallbackParameter, предоставленное в буфере, который был передан в функцию adi_dev_SequentialIO().

ADI_TWI_EVENT_YANKED. Буфер был удален из очереди передачи или приема. Это событие происходит, когда произошла ошибка передачи/приема буфера, и есть последующие буферы в цепочке, которые требуют повтора Start с адресом устройства. Value - буфер, который был удален.

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

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

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

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

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

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

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

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

ADI_TWI_RESULT_BAD_RATE. Скорость данных (data rate), переданная команде ADI_TWI_CMD_SET_RATE, вышла за пределы допустимых значений. Частота (frequency) должна быть в диапазоне 20 .. 400, и скважность (duty cycle) в диапазоне 1 .. 99. В зависимости от частоты тактов Blackfin к этой ошибке могут приводить другие значения.

ADI_TWI_RESULT_BAD_ADDR. Был передан недопустимый адрес либо в режиме подчиненного устройства (slave mode, с командой ADI_TWI_CMD_SET_SLAVE), либо в режиме главного устройства (master mode, поле pAdditionalInfo). Адрес должен быть в диапазоне 8 .. 123, или ADI_TWI_RSTART_ADDR.

ADI_TWI_RESULT_NO_DATA. Предоставленный буфер (read/write/sequential) не содержит данных.

ADI_TWI_RESULT_SLAVE_DCB. Устройство было сконфигурировано для slave mode, и использует отложенные функции обратного вызова (deferred callbacks). Это может вызвать проблемы, потому что драйвер ждет другой буфер для передачи/приема данных от/в шину, и шина при этом занята драйвером TWI.

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

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

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

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

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

Таблица 4. Настройки по умолчанию.

Опция По умолчанию Возможные значения Command ID
Аппаратная конфигурация ADI_INT_TWI Зависит от используемого процессора Blackfin ADI_TWI_CMD_SET_HARDWARE
Rate (скорость обмена) Frequency=100
Duty cycle=50
Frequency 20..400
Duty cycle 1..99
ADI_TWI_CMD_SET_RATE
FIFO 0x000C 0x0000, 0x0004, 0x0008 и 0x000C ADI_TWI_CMD_SET_FIFO
Lost arbitration 3 0..255 ADI_TWI_CMD_SET_LOSTARB
ANAK 1 0..255 ADI_TWI_CMD_SET_ANAK
DNAK 1 0..255 ADI_TWI_CMD_SET_DNAK
SCL override 0 0, 1 ADI_TWI_CMD_SET_SCLOVR
SDA override 0 0, 1 ADI_TWI_CMD_SET_SDAOVR
General call 0 1 (после установки сбросить нельзя) ADI_TWI_CMD_SET_GCALL
SCCB mode 0 1 (после установки сбросить нельзя) ADI_TWI_CMD_SET_SCCB
Pseudo-конфигурация 0 См. примеры ниже ADI_TWI_CMD_SET_PSEUDO

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

Таблица 5. Дополнительные требуемые настройки.

Опция Возможные значения Command ID
Метод потока данных См. выше "Методы поддержки потока данных". ADI_DEV_CMD_SET_DATAFLOW_METHOD
Pseudo-конфигурация Структура adi_twi_pseudo_port определяет используемую аппаратуру, см. примеры ниже. ADI_TWI_CMD_SET_PSEUDO

[Что следует учесть при работе с аппаратурой]

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

Частота (frequncy) в pseudo-режиме может быть неточной в зависимости от скорости процессора и выбранного значения frequency. Из-за программной нагрузки на этот драйвер накладывается ограничение минимальной скорости таймера 10000 тактовых циклов. Это конфигурируется в adi_twi.c путем изменения определения ADI_TWI_PSEUDO_PERIOD.

Замечание: ножки SCL и SDA требуют подключения внешнего верхнего подтягивающего резистора (pull-up). Для дополнительной информации см. требования в даташитах используемых I2C-устройств. В качестве примера можно посмотреть схему платы разработчика ADSP-BF537 EZ-Kit Lite, где применены такие резисторы.

Структура TWI Pseudo Port, передаваемая с командой ADI_TWI_CMD_SET_PSEUDO:

// Структура, используемая для программной эмуляции порта TWI.
typedef struct
{
   ADI_FLAG_ID scl;  // Идентификатор флага (ножки порта), используемого для сигнала SCL.
   ADI_FLAG_ID sda;  // Идентификатор флага (ножки порта), используемого для сигнала SDA.
   u32 timer;        // Таймер, который используется для тактирования pseudo TWI.
   ADI_INT_PERIPHERAL_ID scl_pid;   // Идентификатор прерывания тактов.
} adi_twi_pseudo_port;

Структура TWI bit rate, передаваемая с командой ADI_TWI_CMD_SET_RATE:

// Структура, определяющая тайминг порта TWI.
typedef struct
{
   u16 frequency;    // Скорость (bit rate) TWI, определенная как частота в килогерцах.
   u16 duty_cycle;   // Скважность (duty cycle), в pseudo mode не используется.
} adi_twi_bit_rate;

[С арбитражем]

Конфигурирование TWI как псевдо-порта с сигналом SCL на флаге PG1 и сигналом SDA на флаге PG0. TWI тактируется от ADI_TMR_GP_TIMER_2, и прерывания флага происходят на ADI_INT_PORTG_B для арбитража мастера шины.

Замечание: при использовании арбитража следует следует соблюдать осторожность, когда происходят прерывания на банке флагов, и если они не сконфигурированы корректно. При этом прерывания могут вызывать другие выводы, что приведет к вызову обработчика флага pseudo TWI и зависанию процессора. Это может произойти, если обрабатывается другой флаг на том же банке, и прерывание вызывается слишком быстро (например, 8-разрядный PPI0 на BF537, когда используется ADI_INT_PORTFG_A или ADI_INT_PORTG_B).

adi_twi_pseudo_port port =
{
   ADI_FLAG_PG1,
   ADI_FLAG_PG0,
   ADI_TMR_GP_TIMER_2,
   ADI_INT_PORTG_B
};
 
// Конфигурационная таблица для драйвера TWI:
ADI_DEV_CMD_VALUE_PAIR config[] =
{
   {ADI_TWI_CMD_SET_PSEUDO,            (void *)(&port)},
   {ADI_DEV_CMD_SET_DATAFLOW_METHOD,   (void *)ADI_DEV_MODE_SEQ_CHAINED},
   {ADI_TWI_CMD_SET_FIFO,              (void *)0x0000},
   {ADI_TWI_CMD_SET_LOSTARB,           (void *)1},
   {ADI_TWI_CMD_SET_ANAK,              (void *)0},
   {ADI_TWI_CMD_SET_DNAK,              (void *)0},
   {ADI_DEV_CMD_SET_DATAFLOW,          (void *)TRUE},
   {ADI_DEV_CMD_END,                   NULL}
};
 
adi_dev_Open(ManagerHandle,
             &ADITWIEntryPoint,
             DeviceNumber,
             DeviceHandle,
             &PhysicalDevice,
             ADI_DEV_DIRECTION_BIDIRECTIONAL,
             NULL,
             DCBHandle,
             DMCallback);
 
adi_dev_Control(device, ADI_DEV_CMD_TABLE, config);

[Без арбитража]

Конфигурирование TWI как псевдо-порта с сигналом SCL на флаге PG1 и сигналом SDA на флаге PG0. TWI тактируется от ADI_TMR_GP_TIMER_2.

adi_twi_pseudo_port port =
{
   ADI_FLAG_PG1,
   ADI_FLAG_PG0,
   ADI_TMR_GP_TIMER_2,
   (ADI_INT_PERIPHERAL_ID)NULL
};
 
// Конфигурационная таблица для драйвера TWI:
ADI_DEV_CMD_VALUE_PAIR config[] =
{
   {ADI_TWI_CMD_SET_PSEUDO,            (void *)(&port)},
   {ADI_DEV_CMD_SET_DATAFLOW_METHOD,   (void *)ADI_DEV_MODE_SEQ_CHAINED},
   {ADI_TWI_CMD_SET_FIFO,              (void *)0x0000},
   {ADI_TWI_CMD_SET_LOSTARB,           (void *)1},
   {ADI_TWI_CMD_SET_ANAK,              (void *)0},
   {ADI_TWI_CMD_SET_DNAK,              (void *)0},
   {ADI_DEV_CMD_SET_DATAFLOW,          (void *)TRUE},
   {ADI_DEV_CMD_END,                   NULL}
};
 
adi_dev_Open(ManagerHandle,
             &ADITWIEntryPoint,
             DeviceNumber,
             DeviceHandle,
             &PhysicalDevice,
             ADI_DEV_DIRECTION_BIDIRECTIONAL,
             NULL,
             DCBHandle,
             DMCallback);
 
adi_dev_Control(device, ADI_DEV_CMD_TABLE, config);

[Ссылки]

1Blackfin ADSP-BF538.
2VDK: менеджер драйверов устройств.
3VDK: менеджер прерываний.
4Аппаратный драйвер I2C/TWI для Blackfin.

 

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


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

Top of Page