CC2652 Serial Peripheral Interface (SPI) Driver Interface

 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
@file       C:\ti\simplelink_cc13xx_cc26xx_sdk_7_10_01_24\source\ti\drivers\SPI.h
@brief      Serial Peripheral Interface (SPI) Driver Interface
 
@anchor ti_drivers_SPI_Overview
# Обзор
Драйвер последовательного периферийного интерфейса (SPI) — это универсальный полнодуплексный драйвер, который передает и получает данные по шине SPI. SPI иногда называют SSI (синхронный последовательный интерфейс). Протокол SPI определяет формат передачи данных по шине SPI, но оставляет управление потоком, форматирование данных и механизмы установления связи на программных уровнях более высокого уровня.
 
Драйвер SPI оперирует некоторыми ключевыми определениями и предположениями:
- Драйвер работает прозрачно при выборе чипа. Некоторые контроллеры SPI оснащены аппаратным чипом для выбора периферийных        периферийных устройств SPI. См. требования к выбору микросхемы в конкретных реализациях устройств.
- Протокол SPI не учитывает встроенный механизм установления связи, как и этот драйвер SPI. Следовательно, при работе в режиме #SPI_PERIPHERAL приложение должно предоставить такой механизм, чтобы гарантировать, что периферийное устройство SPI готово к работе с контроллером SPI. Периферийное устройство SPI должно вызвать #SPI_transfer() *прежде*, чем* контроллер SPI начнет передачу.
Некоторые примеры механизмов применения могут включать:
- Временные задержки на контроллере SPI, гарантирующие готовность периферийного устройства SPI к транзакции SPI.
- Форма управления потоком GPIO от периферийного устройства к контроллеру SPI для уведомления контроллера о готовности.
 
 
@anchor ti_drivers_SPI_Usage
# Использование
 
Чтобы использовать драйвер SPI для отправки данных по шине SPI, приложение вызывает следующие API:
- SPI_init(): инициализировать драйвер SPI.
- SPI_Params_init(): инициализировать структуру #SPI_Params значениями по умолчанию. Затем при необходимости измените параметры со значений, отличных от значений по умолчанию.
- SPI_open(): открыть экземпляр драйвера SPI, передав инициализированные параметры или NULL и индекс открываемой конфигурации (подробно позже).
- SPI_transfer(): передача/получение данных. Эта функция принимает аргумент #SPI_Transaction, который описывает запрошенную передачу.
- SPI_close(): деинициализировать экземпляр SPI.
 
@anchor ti_drivers_SPI_Synopsis
## Краткое описание
Следующий пример кода открывает экземпляр SPI в качестве контроллера SPI и выполняет транзакцию.
  SPI_Handle      spi;
  SPI_Params      spiParams;
  SPI_Transaction spiTransaction;
  uint8_t         transmitBuffer[MSGSIZE];
  uint8_t         receiveBuffer[MSGSIZE];
  bool            transferOK;
 
  SPI_init();  // Инициализируйте драйвер SPI
 
  SPI_Params_init(&spiParams);  // инициализировать параметры SPI
  spiParams.dataSize = 8;       // 8-bit data size
 
  spi = SPI_open(CONFIG_SPI0, &spiParams);
  if (spi == NULL) {
      while (1);  // SPI_open() failed
  }
 
  // Заполните передающий буфер
  spiTransaction.count = MSGSIZE;
  spiTransaction.txBuf = (void *)transmitBuffer;
  spiTransaction.rxBuf = (void *)receiveBuffer;
 
  transferOK = SPI_transfer(spi, &spiTransaction);
  if (!transferOK) {
      // Error in SPI or transfer already in progress.
      while (1);
 }
 
Более подробная информация об использовании представлена в следующих подразделах.
 
@anchor ti_drivers_SPI_Examples
## Примеры #
@ref ti_drivers_SPI_Synopsis «Краткий обзор использования»
@ref ti_drivers_SPI_Example_openblocking «Открыть в режиме блокировки»
@ref ti_drivers_SPI_Example_opencallback «Открыть в режиме обратного вызова»
@ref ti_drivers_SPI_Example_6bitframes «Отправка 6-битных кадров»
@ref ti_drivers_SPI_Example_12bitframes «Отправка 12-битных кадров»
@ref ti_drivers_SPI_Example_callbackarg «Функция обратного вызова с использованием arg»
 
## Инициализация драйвера SPI
SPI_init() должен вызываться перед любыми другими API SPI. Эта функция перебирает элементы массива @p SPI_config[], вызывая функцию инициализации SPI реализации устройства элемента.
 
## Открытие драйвера SPI
После инициализации драйвера SPI вызовом SPI_init() приложение может открыть экземпляр SPI вызовом SPI_open(). Эта функция принимает индекс массива @p SPI_config[] и структуру данных параметров SPI. Экземпляр SPI указывается индексом SPI в @p SPI_config[]. Вызов SPI_open() второй раз с тем же индексом, который ранее был передан в SPI_open(), приведет к ошибке. Однако вы можете повторно использовать индекс, если экземпляр закрыт с помощью SPI_close().
 
Если структура #SPI_Params не передается в SPI_open(), используются значения по умолчанию. Если открытый вызов успешен, он возвращает значение, отличное от NULL.
 
@anchor ti_drivers_SPI_Example_openblocking
Пример открытия экземпляра драйвера SPI в режиме блокировки:
 
 SPI_Handle  spi;
 SPI_Params  spiParams;
 
 SPI_Params_init(&spiParams);
 spiParams.transferMode = SPI_MODE_BLOCKING;
 spi = SPI_open(CONFIG_SPI0, &spiParams);
  if (spi == NULL) {
      // Error opening SPI
      while(1);
  }
 
@anchor ti_drivers_SPI_Example_opencallback
Пример открытия экземпляра драйвера SPI в режиме обратного вызова:
 
SPI_Handle spi;
SPI_Params spiParams;
 
SPI_Params_init(&spiParams);
spiParams.transferMode = SPI_MODE_CALLBACK;
spiParams.transferCallbackFxn = UserCallbackFxn;
 
spi = SPI_open(CONFIG_SPI0, &spiParams);
if (spi == NULL) {
      // Error opening SPI
      while (1);
}
 
## Параметры SPI
 
Структура #SPI_Params передается вызову SPI_open(). Если NULL передается в качестве параметров, SPI_open() использует параметры по умолчанию.
Структура #SPI_Params инициализируется значениями по умолчанию путем передачи ее в SPI_Params_init().
Некоторые параметры SPI описаны ниже. Чтобы просмотреть краткие описания всех параметров, см. #SPI_Params.
 
### Режим SPI
Драйвер SPI работает как в режиме контроллера SPI, так и в режиме периферийного устройства SPI.
Логически реализация идентична, однако разница между этими двумя режимами обусловлена аппаратным обеспечением. Режим по умолчанию — #SPI_CONTROLLER, но его можно установить в периферийный режим, установив для #SPI_Params.mode значение #SPI_PERIPHERAL в параметрах, передаваемых в SPI_open().
Дополнительную информацию см. в разделе @ref ti_drivers_SPI_ControllerPeripheralModes «Режимы контроллера/периферийных устройств».
 
### Режим передачи SPI
Драйвер SPI поддерживает два режима работы передачи: блокировка и обратный вызов. Режим передачи определяется параметром TransferMode в структуре данных #SPI_Params. Драйвер SPI по умолчанию работает в режиме блокировки, если приложение не устанавливает его.
После открытия драйвера SPI единственный способ изменить режим работы — закрыть и повторно открыть экземпляр SPI с новым режимом передачи.
 
В режиме блокировки выполнение кода задачи блокируется до тех пор, пока транзакция SPI не завершится или не истечет время ожидания. Это гарантирует, что в данный момент времени работает только одна передача SPI. Другие задачи, запрашивающие передачу SPI во время ее выполнения, получат возвращаемое значение FALSE. Если происходит тайм-аут, передача отменяется, задача разблокируется и получает возвращаемое значение FALSE. Поле количества транзакций будет содержать количество кадров, которые были успешно переданы до истечения времени ожидания. В режиме блокировки передачи не могут выполняться в контексте программного или аппаратного ISR.
 
В режиме обратного вызова транзакция SPI работает асинхронно, что означает, что она не блокирует выполнение кода. После завершения транзакции SPI драйвер SPI вызывает предоставленную пользователем функцию перехвата.
Режим обратного вызова поддерживается в контексте выполнения задач и процедур аппаратного прерывания.
 
### Форматы кадров SPI и размер данных
Драйвер SPI может настроить периферийное устройство SPI устройства для передачи данных в нескольких вариантах формата SPI: SPI (с различными настройками полярности и фазы), TI и Micro-wire. Формат кадра задается с помощью #SPI_Params.frameFormat. Некоторые реализации SPI могут не поддерживать все форматы кадров, и драйвер SPI не откроется. Подробную информацию о поддерживаемых форматах кадров см. в документации по реализации конкретного устройства.
 
Наименьшая единица данных, передаваемая по шине SPI, называется кадром SPI и имеет размер #SPI_Params.dataSize. Серия кадров SPI, передаваемых/полученных по шине SPI, называется транзакцией SPI.
 
## Транзакции SPI
 
Транзакция SPI состоит из серии кадров SPI, передаваемых/полученных по шине SPI. Транзакция SPI выполняется с помощью SPI_transfer(). SPI_transfer() принимает указатель на структуру #SPI_Transaction, которая определяет количество данных, которые необходимо отправить и получить.
#SPI_Transaction.txBuf и #SPI_Transaction.rxBuf оба являются указателями на буферы данных. Если txBuf имеет значение NULL, драйвер отправляет кадры SPI со всеми данными, установленными в значение по умолчанию, указанное в атрибутах оборудования. Если rxBuf имеет значение NULL, драйвер отбрасывает все полученные кадры SPI. SPI_transfer() транзакции SPI выполняется атомарно.
 
@warning Использование NULL в качестве контрольного значения txBuf или rxBuf для определения того, включает ли транзакция SPI компонент tx или rx, подразумевает, что невозможно выполнить передачу или прием передачи непосредственно из/в буфер с базовым адресом 0x00000000 . Для поддержки этого редкого варианта использования приложению придется вручную скопировать содержимое местоположения 0x00000000 во временный буфер или из него до или после транзакции SPI tx/rx.
 
Когда SPI открыт, значение dataSize определяет типы элементов txBuf и rxBuf. Если dataSize составляет от 4 до 8 бит, драйвер предполагает, что буферы данных имеют тип uint8_t (беззнаковый символ). Если dataSize составляет от 8 до 16 бит, драйвер предполагает, что буферы данных имеют тип uint16_t (беззнаковое короткое). Если dataSize больше 16 бит, драйвер предполагает, что буферы данных имеют тип uint32_t (длина без знака).
Некоторые реализации драйвера SPI могут поддерживать не все размеры данных; Подробную информацию о поддерживаемых размерах данных см. в документации по реализации SPI для конкретного устройства.
 
Необязательную переменную #SPI_Transaction.arg можно использовать только в том случае, если драйвер SPI открыт в режиме обратного вызова. Эта переменная используется для передачи определяемого пользователем значения в определяемую пользователем функцию обратного вызова.
 
SPI_transfer() всегда выполняет полнодуплексные транзакции SPI. Это означает, что SPI одновременно получает данные и передает их. Приложение отвечает за форматирование передаваемых данных, а также за определение значимости полученных данных.
Подробные сведения о форматировании кадра SPI и размерах данных приведены в таблицах технических данных для конкретных устройств и технических справочных руководствах.
 
Следующие фрагменты кода выполняют транзакции SPI.
 
@anchor ti_drivers_SPI_Example_6bitframes
Пример передачи 6-битных кадров SPI. Буферы передачи и приема имеют тип uint8_t.
 
  SPI_Transaction spiTransaction;
  uint8_t         transmitBuffer[BUFSIZE];
  uint8_t         receiveBuffer[BUFSIZE];
  bool            transferOK;
 
  SPI_Params_init(&spiParams);
  spiParams.dataSize = 6;
  spi = SPI_open(CONFIG_SPI0, &spiParams);
  ...
  spiTransaction.count = someIntegerValue;
  spiTransaction.txBuf = transmitBuffer;
  spiTransaction.rxBuf = receiveBuffer;
 
  transferOK = SPI_transfer(spi, &spiTransaction);
  if (!transferOK) {
      // Error in SPI or transfer already in progress.
  }
 
@anchor ti_drivers_SPI_Example_12bitframes
Пример передачи 12-битных кадров SPI. Буферы передачи и приема имеют тип uint16_t.
 
  SPI_Transaction spiTransaction;
  uint16_t        transmitBuffer[BUFSIZE];
  uint16_t        receiveBuffer[BUFSIZE];
  bool            transferOK;
 
  SPI_Params_init(&spiParams);
  spiParams.dataSize = 12;
  spi = SPI_open(CONFIG_SPI0, &spiParams);
  ...
  spiTransaction.count = someIntegerValue;
  spiTransaction.txBuf = transmitBuffer;
  spiTransaction.rxBuf = receiveBuffer;
 
  transferOK = SPI_transfer(spi, &spiTransaction);
  if (!transferOK) {
      // Error in SPI or transfer already in progress.
  }
 
В следующем примере показан пример функции обратного вызова, использующей параметр arg.
@anchor ti_drivers_SPI_Example_callbackarg
 
// SPI открывается с помощью функции обратного вызова, как показано в других примерах
// Наша цель — опубликовать семафор после завершения передачи достаточного размера.
...
// Передаем указатель на инициализированный семафор для обратного вызова через arg
 spiTransaction.count = someIntegerValue;
 spiTransaction.txBuf = transmitBuffer;
 spiTransaction.rxBuf = receiveBuffer;
 spiTransaction.arg   = &mySemaphore;
  ...
 // Здесь определена наша функция обратного вызова
  void spiCallbackFxn(SPI_Handle spi, SPI_Transaction *tran)
  {
     sem_t *semPtr = (sem_t *)(tran->arg);
 
      // Опубликуйте семафор, если наша транзакция превысила LIMIT.
     if (tran->status == SPI_STATUS_SUCCESS &&
          tran->count > LIMIT) {
          sem_post(semPtr);
     }
  }
## Отмена транзакции
SPI_transferCancel() используется для отмены транзакции SPI, когда драйвер используется в режиме #SPI_MODE_CALLBACK.
 
Вызов этого API во время отсутствия передачи не имеет никакого эффекта. Если передача выполняется, она отменяется и вызывается функция обратного вызова.
Поле статуса #SPI_Status в структуре #SPI_Transaction можно проверить в обратном вызове, чтобы определить, была ли транзакция успешной.
 
Пример:
 
SPI_transferCancel(spi);
 
@anchor ti_drivers_SPI_ControllerPeripheralModes
## Режимы контроллера/периферийных устройств
Этот драйвер SPI работает как в режиме контроллера SPI, так и в режиме периферийного устройства SPI.
Логически реализация идентична, однако разница между этими двумя режимами обусловлена аппаратным обеспечением. Будучи контроллером SPI, периферийное устройство контролирует тактовый сигнал и поэтому немедленно начнет связь с периферийным устройством SPI. В качестве периферийного устройства SPI драйвер SPI подготавливает периферийное устройство для передачи и приема данных таким образом, чтобы периферийное устройство было готово передавать данные, когда контроллер SPI инициирует транзакцию.
 
## Подтверждение выбора чипа
Протокол SPI требует, чтобы контроллер SPI подтвердил вывод выбора микросхемы периферийного устройства SPI перед началом транзакции SPI. Хотя этот протокол обычно соблюдается, различные типы периферийных устройств SPI имеют разные требования к времени относительно того, когда и как долго вывод выбора чипа должен оставаться активным для транзакции SPI.
 
Обычно контроллер SPI использует выбор аппаратного чипа для подтверждения и отмены подтверждения периферийного устройства SPI для каждого кадра данных. В других случаях периферийное устройство SPI налагает требование подтверждения выбора чипа для нескольких кадров данных SPI. Обычно это достигается использованием обычного выходного контакта общего назначения. Из-за сложности таких реализаций периферийных устройств SPI этот драйвер SPI был разработан так, чтобы работать прозрачно для выбора чипа SPI. Когда используется аппаратный выбор  чипа, периферийное устройство автоматически выбирает/включает периферийное устройство. При использовании программного выбора чипа приложение должно обеспечить правильный выбор чипа и конфигурацию контактов. Поддержка выбора чипа зависит от периферийного устройства SPI. Подробную информацию о поддержке выбора чипа см. в документации по реализации конкретного устройства.
 
- _Выбор аппаратного чипа_ Никаких дополнительных действий со стороны приложения не требуется.
- _Программный выбор чипа_ Приложению необходимо обрабатывать утверждение и отмену выбора чипа для соответствующего периферийного устройства SPI.
 
@anchor ti_drivers_SPI_Configuration
# Конфигурация
 
Чтобы использовать API SPI, приложению необходимо предоставить конфигурацию SPI для конкретного устройства в файле ti_drivers_config.c.
Интерфейс драйвера SPI определяет структуру данных конфигурации:
  typedef struct  {
      SPI_FxnTable  const    *fxnTablePtr;
      void                   *object;
      void          const    *hwAttrs;
  } SPI_Config;
 
Приложение должно объявить массив элементов #SPI_Config с именем @p SPI_config[]. Каждый элемент @p SPI_config[] должен быть заполнен указателями на таблицу функций реализации драйвера SPI конкретного устройства, объект драйвера и атрибуты оборудования. Атрибуты оборудования определяют такие свойства, как базовый адрес периферийного устройства SPI и контакты PICO и POCI. Каждый элемент в @p SPI_config[] соответствует экземпляру SPI, и ни один из элементов не должен иметь NULL-указателей. Между индексом и обозначением периферии (например, SPI0 или SPI1) нет корреляции. Например, можно использовать SPI_config[0] для SPI1.
 
Поскольку конфигурация SPI во многом зависит от устройства, вам необходимо проверить doxygen на предмет реализации SPI для конкретного устройства. Там вы найдете описание аппаратных атрибутов SPI. Также обратитесь к файлу ti_drivers_config.c любого из ваших примеров, чтобы увидеть конфигурацию SPI.
 
Ваша оценка: None Средняя: 10 (1 голос)