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

Analog Devices разработала для платформы Blackfin два драйвера для интерфейса I2C (TWI) - один аппаратный (adi_twi), другой программный (adi_twi_pseudo). Этот документ (перевод файла документации Blackfin\docs\drivers\twi\adi_twi.pdf, входящий в комплект поставки VisualDSP++) описывает работу только аппаратного драйвера TWI (информацию по программной реализации TWI см. документ adi_twi_pseudo.pdf, находящийся в том же каталоге системы VisualDSP). Аппаратный драйвер TWI поддерживает оба режима работы шины I2C - главного устройства (master mode) и подчиненного устройства (slave mode).

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

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

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

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

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

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

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

Прерывания. Этот драйвер TWI использует одно прерывание - TWI hardware interrupt.

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

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

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

Программируемые флаги. Драйвер TWI не использует какие-либо выводы процессора (GPIO, компания Analog Devices почему-то называет их программируемыми флагами).

Используемые выводы. Интерфейс TWI и его драйвер для соединения с внешним миром использует 2 сигнальных провода - SCL и SDA. Они могут меняться в зависимости от типа используемого Blackfin, подробности см. в даташите на процессор (например, у Blackfin ADSP-BF538 [1] два аппаратных интерфейса TWI).

Замечание: не у всех моделей процессоров Blackfin есть на борту встроенный аппаратный интерфейс TWI. Если Ваш процессор не имеет аппаратного TWI, то можно использовать программную реализацию драйвера TWI [4] (TWI Pseudo driver), который эмулирует поведение интерфейса TWI на обычных выводах портов (GPIO) процессора.

[Функции, поддерживаемые драйвером 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_CHAINED Поддерживает метод цепочек буферов. Этот метод буфера переводит устройство TWI в режим подчиненного (slave).
ADI_DEV_MODE_SEQ_CHAINED Поддерживает последовательный поток данных ввода/вывода (цепочки буферов). Этот метод переводит устройство TWI в режим главного (мастер шины, master I2C).

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

ADI_DEV_1D_BUFFER. Это линейный одномерный (1D) буфер. Поле pAdditionalInfo структуры буфера игнорируется.

ADI_DEV_SEQ_1D_BUFFER. Это линейная одномерная цепочка буферов. Поле pAdditionalInfo имеет тип u32, оно используется (для передачи значения адреса в подчиненного устройства в режиме master (диапазон адреса 8 .. 123). Опционально адрес может быть объединен операцией ИЛИ с макросом ADI_TWI_REPEAT_START, если при перемещении данных повтор сигнала Start (это важно для систем multi-master, см. врезку ниже).

Во время передач TWI часто нужно сначала отправить команду, и затем сразу же прочитать обратно ответ. Это должно быть сделано, чтобы в системе с несколькими устройствами master не было риска вмешательства в эту атомарную операцию другого master-устройства. В протоколе TWI определено понятие "repeated start condition" (повторная отправка сигнала Start) для реализации этой функции. Обычно после отправки байта адреса (в котором содержится адрес I2C и бит чтения/записи R/W) мастер может отправить любое количество байт, за которым следует сигнал Stop. Вместо отправки сигнала Stop также можно отправить другой (повторный) сигнал Start, за которым снова идет адрес устройства (конечно также с битом R/W) и другие данные. Это определено рекурсивно, позволяя отправлять любое количество повторных (repeated) сигналов Start. Эта возможность предназначена для того, чтобы комбинировать операции записи/чтения без освобождения шины, что гарантировало бы непрерывность (атомарность) всей операции. Независимо от количества отправленных за одно перемещение данных сигналов Start, передача должна быть завершена только одним сигналом Stop.

В случае одномерного цепочечного буфера (1D sequential buffer, ADI_DEV_SEQ_1D_BUFFER) пользователи могут конфигурировать repeated start condition путем наложения по ИЛИ макроса ADI_TWI_REPEAT_START на требуемый адрес подчиненного устройства, и установки этого полученного значения в поле pAdditionalInfo структуры буфера. Последний буфер в такой цепочке буферов не должен использовать repeated start condition, чтобы гарантировать завершение последовательности сигналом Stop.

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

ADI_TWI_CMD_SET_PSEUDO. Устанавливает TWI в псевдо-режим (программная реализация TWI, см. [4]). 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-разрядное значение адреса подчиненного устройства).

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 - буфер, который был удален.

[События slave mode]

ADI_TWI_EVENT_XMT_NEED. Драйвер передал все данные, и требует предоставления нового буфера. Value - не используется.

ADI_TWI_EVENT_XMT_PROCESSED. Был обработан буфер, переданный драйверу функцией adi_dev_Write(). Value - значение CallbackParameter, предоставленное в буфере, который был предоставлен для функции adi_dev_Write().

ADI_TWI_EVENT_RCV_NEED. Драйвер принял байт в slave mode, и нужен буфер, чтобы положить в него принятые данные. Value - не используется.

ADI_TWI_EVENT_RCV_PROCESSED. Был обработан буфер, переданный драйверу функцией adi_dev_Read(). Value - значение CallbackParameter, предоставленное в буфере, который был предоставлен для функции adi_dev_Read().

ADI_TWI_EVENT_SERR. Буфер чтения был возвращен с неожиданной остановкой. Value - не используется.

ADI_TWI_EVENT_SOVF. В буфере чтения есть данные от двух передач. Value - не используется.

ADI_TWI_EVENT_GCALL. Были приняты данные адреса общего вызова (General Call address). Value - значение CallbackParameter, предоставленное в буфере, который был предоставлен для функции adi_dev_Read(), adi_dev_Write() или adi_dev_SequentialIO().

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

Все 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, если используется repeated start condition - см. врезку в секции описания типов буфера).

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

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

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

Опция Возможные значения Command ID
Метод потока данных См. выше "Методы поддержки потока данных" ADI_DEV_CMD_SET_DATAFLOW_METHOD

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

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

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

Структура TWI Pseudo Port, передаваемая с командой ADI_TWI_CMD_SET_PSEUDO (см. [4]):

// Структура, используемая для программной эмуляции порта 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 как hardware master, скорость установлена на 100 кГц, скважность 50%, прерывания происходят на байтах, и буфер отбрасывается, если удовлетворяется условие LOSTARB.

adi_twi_bit_rate rate = {100, 50};
 
// Конфигурационная таблица для драйвера TWI:
ADI_DEV_CMD_VALUE_PAIR config_master[] =
{ 
   {ADI_TWI_CMD_SET_HARDWARE,          (void *)ADI_INT_TWI},
   {ADI_DEV_CMD_SET_DATAFLOW_METHOD,   (void *)ADI_DEV_MODE_SEQ_CHAINED},
   {ADI_TWI_CMD_SET_FIFO,              (void *)0x0000},
   {ADI_TWI_CMD_SET_RATE,              (void *)(&rate)},
   {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_master);

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

// Конфигурационная таблица для драйвера TWI:
ADI_DEV_CMD_VALUE_PAIR config_slave[] =
{
   {ADI_TWI_CMD_SET_HARDWARE,          (void *)ADI_INT_TWI},
   {ADI_DEV_CMD_SET_DATAFLOW_METHOD,   (void *)ADI_DEV_MODE_CHAINED},
   {ADI_TWI_CMD_SET_FIFO,              (void *)0x000C},
   {ADI_TWI_CMD_SET_SLAVE_ADDR,        (void *)0x60},
   {ADI_DEV_CMD_SET_DATAFLOW,          (void *)TRUE},
   {ADI_DEV_CMD_END,                   NULL}
};

[Ссылки]

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