У процессоров ADSP-BF538/ADSP-BF538F Blackfin (далее в тексте просто BF538) есть богатый набор различных периферийных устройств, которые могут использоваться в приложениях. Функция GPIO (general-purpose input/output, порты ввода/вывода общего назначения) мультиплексируются на выводах корпуса процессора с функциями периферийных устройств. Функционал GPIO может быть разрешен для каждого вывода индивидуально - вместо функционала периферийных устройств.
Выводы GPIO сгруппированы в порты C, D, E (есть также и порт F, но его программирование и использование имеет отличия, поэтому порт F рассмотрен в отдельной статье [2]). Каждый вывод в группе может быть запрограммирован индивидуально. Если приложение, применяющее периферийное устройство, не требует использования всех выводов этого периферийного устройства, то все ненужные выводы периферийного устройства могут быть сконфигурированы как порты GPIO. В таблице 15-1 показано, как периферийные устройства привязаны к портам GPIO.
Таблица 15-1. Мультиплексирование функций GPIO и периферийных устройств на выводах процессора.
Порт
Основная функция (по умолчанию)
Альтернативная функция
Port C
CAN GPIO
PC1:0 PC9:4
Port D
SPI1 SPI2 UART1 UART2
PD4:0 PD9:5 PD11:10 PD13:12
Port E
SPORT2 SPORT3
PE7:0 PE15:8
Функции по умолчанию, альтернативные функции. Функции, которые можно программно настроить на выводах процессора (т. е. изменить их первоначальное состояние по умолчанию на другое), называются альтернативными. Таким образом, каждый вывод порта может нести 2 программно выбираемые функции - функция по умолчанию, или первичная, основная функция (которая работает после сброса / включения питания) и альтернативная функция.
Функционал GPIO портов C, D и E отличается от порта F двумя моментами:
1. На портах C, D и E нет возможности генерировать прерывания по состоянию лог. уровня на выводе и по перепадам этого уровня. 2. Разрешение GPIO и управление на портах C, D и E никак не связано с чтением и записью любых регистров периферийного устройства.
Сразу после системного сброса весь функционал GPIO запрещен, и выводы переключаются на обслуживание функций периферийных устройств. Таким образом, после сброса вывод периферийного устройства (где могла бы быть функция GPIO) работает по своему назначению, как если бы этому выводу было назначено работать для периферийного устройства, без наличия мультиплексированного функционала GPIO. Но вывод может быть сконфигурирован на работу как GPIO путем записи соответствующего бита в регистр конфигурации GPIO (PORTxIO_FER). Как только вывод сконфигурирован в работе как GPIO, его направление работы (вход это или выход) можно установить, используя регистры направления GPIO (PORTxIO_DIR). Можно предварительно задать выходное значение для GPIO перед его настройкой для работы в режиме выхода.
Примечание: имена регистров для программирования GPIO используют префикс PORTxIO, где буква x может быть C, D или E.
Есть несколько методов для управления выходным уровнем GPIO с помощью записи значений в регистры. Эти регистры следующие: регистр данных (GPIO data, PORTxIO), регистр установки (PORTxIO_SET), регистр очистки (PORTxIO_CLEAR), и регистр переключения уровня в противоположное значение (PORTxIO_TOGGLE). Для управления состоянием выходов может использоваться метод записать-1-для_действия, что устраняет проблемы когерентности, обычно возникающие с методами доступа типа последовательности read-modify-write.
Оба эти термина связаны с необходимостью управлять состоянием только одного бита за одну операцию. Поскольку биты, соответствующие выводам портов, объединены в слово разрядностью 16 бит, то традиционным способом поменять состояние только одного бита можно только с помощью последовательности операций прочитать, поменять прочитанное значение и записать. Это как раз и называется операцией read-modify-write.
Проблема с операцией read-modify-write состоит в том, что с традиционным доступом к регистрам такое управление битами трудно сделать атомарным. Вот тут как раз и приходит на помощь принцип управления битами write-1-to-действие (записать лог. 1, чтобы выполнить действие) - благодаря наличию отдельного регистра для каждого действия (сброс, установка, переключение) появляется возможность атомарно управлять значением любого отдельного бита (или набора битов) за одно быстрое действие.
В таблицах 15-2, 15-3 и 15-4 перечислены все выводы периферийных устройств, у которых может быть назначена функция GPIO. Каждый порт GPIO имеет полный набор регистров, связанных с управлением GPIO этого порта. Номера бит в этих таблицах должны быть использованы для доступа к любому из этих регистров GPIO, потому что относительная позиция бита этого порта сохраняется для всех регистров управления GPIO. Например, если приложение не использует контроллер CAN, то 2 вывода CAN (CANTX и CANRX) могут быть освобождены для работы в качестве GPIO путем установки битов 0 и 1 (т. е. записи лог. 1 в биты 0 и 1) регистра PORTCIO_FER. Начиная с этого момента программное обеспечение может сконфигурировать эти выводы независимо друг от друга (например, как вход или выход), и также независимо друг от друга управлять этими выводами путем записи лог. 0 и лог. 1 в биты 0 и 1 соответствующих регистров GPIO порта C.
Таблица 15-2. GPIO Port C и мультиплексирование функций.
Вывод GPIO порта C
Вывод периферийного устройства, мультиплексированный с функцией GPIO
Соответствующие разряды регистров GPIO
PC0
CAN передача (CANTX)
0
PC1
CAN прием (CANRX)
1
PC4-9
GPIO (нет мультиплексирования с периферийными устройствами)
4-9
Примечание: выводы PC1 и PC4 (разряды 1 и 4) могут быть сконфигурированы как GPIO, однако надо иметь в виду, что в режиме входа это 5V-tolerant вход, а в режиме выхода это выход с открытым стоком. Таким образом, в режиме выхода эти выводы могут быть переведены в состояние лог. 0, если записать в регистр данных значение 0, но если записать лог. 1, то вывод перейдет в третье состояние (состояние отключено). Так что для получения на выходе полноценной лог. 1 необходимо подключить к выводам PC1 и PC4 внешний pull-up резистор.
Таблица 15-3. GPIO Port D и мультиплексирование функций.
Вывод GPIO порта D
Вывод периферийного устройства, мультиплексированный с функцией GPIO
Соответствующие разряды регистров GPIO
PD0
SPI1 Master Out Slave In (MOSI1)
0
PD1
SPI1 Master In Slave Out (MISO1)
1
PD2
SPI1 Clock (SCK1)
2
PD3
SPI1 Slave Select Input (~SPI1SS)
3
PD4
SPI1 Slave Select Enable (~SPI1SEL1)
4
PD5
SPI2 Master Out Slave In (MOSI2)
5
PD6
SPI2 Master In Slave Out (MISO2)
6
PD7
SPI2 Clock (SCK2)
7
PD8
SPI2 Slave Select Input (~SPI2SS)
8
PD9
SPI2 Slave Select Enable (~SPI2SEL1)
9
PD10
UART1 Receive (RX1)
10
PD11
UART1 Transmit (TX1)
11
PD12
UART2 Receive (RX2)
12
PD13
UART2 Transmit (TX2)
13
Таблица 15-4. GPIO Port E и мультиплексирование функций.
Вывод GPIO порта E
Вывод периферийного устройства, мультиплексированный с функцией GPIO
Соответствующие разряды регистров GPIO
PE0
SPORT2 Receive Serial Clock (RSCLK2)
0
PE1
SPORT2 Receive Frame Sync (RFS2)
1
PE2
SPORT2 Receive Data Primary (DR2PRI)
2
PE3
SPORT2 Receive Data Secondary (DR2SEC)
3
PE4
SPORT2 Transmit Serial Clock (TSCLK2)
4
PE5
SPORT2 Transmit Frame Sync (TFS2)
5
PE6
SPORT2 Transmit Data Primary (DT2PRI)
6
PE7
SPORT2 Transmit Data Secondary (DT2SEC)
7
PE8
SPORT3 Receive Serial Clock (RSCLK3)
8
PE9
SPORT3 Receive Frame Sync (RFS3)
9
PE10
SPORT3 Receive Data Primary (DR3PRI)
10
PE11
SPORT3 Receive Data Secondary (DR3SEC)
11
PE12
SPORT3 Transmit Serial Clock (TSCLK3)
12
PE13
SPORT3 Transmit Frame Sync (TFS3)
13
PE14
SPORT3 Transmit Data Primary (DT3PRI)
14
PE15
SPORT3 Transmit Data Secondary (DT3SEC)
15
[Отображаемые на память регистры GPIO]
Регистры, которыми управляются GPIO, являются частью области памяти системных регистров, отображенных на общее адресное пространство процессора (memory-mapped registers, сокращенно MMR). Адреса регистров GPIO MMR даны в Приложении B. Доступ к регистрам GPIO со стороны ядра осуществляется через системную шину.
Регистр разрешения функции GPIO (GPIO function enable register, PORTxIO_FER) является регистром с доступом на чтение и запись. Каждая позиция бита в этом регистре соответствует отдельному выводу GPIO (за исключением разрядов, помеченных на рисунках серым цветом). Значение после сброса равно 0x0000. В этом состоянии все функции GPIO вывода запрещены, и работа вывода зависит от функции периферийного устройства, связанного с этим выводом. Лог. 1, записанная в определенную позицию бита PORTxIO_FER, запрещает функцию периферийного устройства на этом выводе и разрешает работу вывода как GPIO. Запись лог. 0 возвращает функцию вывода под управление периферийным устройством. Чтение не используемых битов PORTxIO_FER всегда вернет значение 0, при этом запись в эти биты не дает никакого эффекта.
Примечания к рис. 15-1:
• Биты PC1 и PC4 (разряды 1 и 4) могут быть сконфигурированы как GPIO, но они работают как 5V-tolerant вход или как выход с открытым стоком (в зависимости от направления работы порта). • Биты от PC4 до PC9 (разряды 4 .. 9) всегда сконфигурированы как GPIO независимо от того, что записано в эти биты регистра PORTCIO_FER (т. е. на этих выводах нет функционала периферийных устройств).
Примечание к рис. 15-1 и 15-2: помеченные серым цветом биты не используются и всегда читаются как 0. Запись в эти биты не дает никакого эффекта.
Рис. 15-1. GPIO Port C Function Enable Register (PORTCIO_FER).
Рис. 15-2. GPIO Port D Function Enable Register (PORTDIO_FER).
Рис. 15-3. GPIO Port E Function Enable Register (PORTEIO_FER).
Регистр направления GPIO (GPIO direction register, PORTxIO_DIR) является регистром для чтения и записи. Каждая позиция бита соответствует определенному выводу GPIO (за исключением разрядов, помеченных на рисунках серым цветом). Если вывод сконфигурирован как GPIO (с помощью регистра PORTxIO_FER), то записанная в бит PORTxIO_DIR лог. 1 разрешает работу вывода GPIO как выхода, переводя его выходной уровень в состояние, определенное регистром PORTxIO. Если записать лог. 0 в разряд PORTxIO_DIR, то соответствующий вывод GPIO будет работать как вход. Значение после сброса для регистра PORTxIO_DIR равно 0x0000, что по умолчанию настраивает все выводы порта как входы (если конечно выводы порта переведены в режим работы GPIO). Чтение не используемых битов (помечены на рисунках серым цветом) всегда возвращает 0, запись в них не дает никакого эффекта.
Примечание к рис. 15-4: выводы PC1 и PC4 (разряды 1 и 4) могут быть сконфигурированы как GPIO, однако надо иметь в виду, что в режиме входа это 5V-tolerant вход, а в режиме выхода это выход с открытым стоком. Таким образом, в режиме выхода эти выводы могут быть переведены в состояние лог. 0, если записать в регистр данных значение 0, но если записать лог. 1, то вывод перейдет в третье состояние (состояние отключено). Так что для получения на выходе полноценной лог. 1 необходимо подключить к выводам PC1 и PC4 внешний pull-up резистор.
Рис. 15-4. GPIO Port C Direction Register (PORTCIO_DIR).
Рис. 15-5. GPIO Port D Direction Register (PORTDIO_DIR).
Рис. 15-6. GPIO Port E Direction Register (PORTEIO_DIR).
Регистр разрешения входа GPIO (GPIO input enable register, PORTxIO_INEN) используется для разрешения работы входных буферов для любого вывода GPIO, который используется как вход. Если оставить входной буфер запрещенным, то это устраняет необходимость подключать внешние подтягивающие резисторы (pull-up или pull-down) в целью получения определенного лог. уровня на входе, когда отдельные выводы GPIO не используются системой. По умолчанию входные буферы запрещены. Чтение не используемых бит PORTxIO_INEN (на рисунках они помечены серым цветом) всегда вернет значение 0, запись в эти биты не дает никакого эффекта.
Если вывод GPIO сконфигурирован как вход, то обязательно также должен быть установлен соответствующий бит в регистре PORTxIO_INEN.
Примечание к рис. 15-7: биты разрешения буфера для PC1 и PC4 (разряды 1 и 4) могут быть установлены, когда эти выводы сконфигурированы как GPIO. В этом случае в режиме входа выводы PC1 и PC4 могут быть 5V-tolerant (т. е. допускать работу с лог. уровнями 5V, даже если это напряжение выше напряжения питания VDDEXT, которое обычно составляет 3.3V).
Рис. 15-7. GPIO Port C Input Enable Register (PORTCIO_INEN).
Рис. 15-8. GPIO Port D Input Enable Register (PORTDIO_INEN).
Рис. 15-9. GPIO Port E Input Enable Register (PORTEIO_INEN).
[Регистры логических значений GPIO]
У процессора есть 4 регистра управления логическими уровнями GPIO (GPIO value registers):
• GPIO data register (PORTxIO), регистр данных GPIO. • GPIO set register (PORTxIO_SET), регистр для установки разрядов GPIO. • GPIO clear register (PORTxIO_CLEAR), регистр для сброса разрядов GPIO. • GPIO toggle register (PORTxIO_TOGGLE), регистр для переключение в противоположное состояние разрядов GPIO.
Эти регистры используются для следующих целей:
• Чтобы определить лог. уровень на любых выводах GPIO, настроенных как входы. • Задать нужный лог. уровень на любых выводах GPIO, настроенных как выходы.
Каждый вывод GPIO представлен соответствующим битом в каждом из этих 4 регистров. Чтение любого из этих регистров даст логический уровень на этих выводах GPIO - т. е. возвращенное значение будет соответствовать состоянию выходов (если соответствующие выводы GPIO настроены как выход) или значению логического сигнала, поданного на вход (если соответствующие выводы GPIO настроены как вход).
Чтение всех этих 4 регистров после сброса даст 0x0000, потому что эти выводы не разрешены, даже если после сброса они находятся в режиме работы входа.
Это регистр данных GPIO (GPIO data register, PORTxIO). Если вывод или выводы настроены как выходы GPIO, то записываемое в регистр данных значение напрямую будет задавать состояние выходов GPIO. При чтении этого регистра будет возвращено значение логического уровня на выводах GPIO. Чтение не используемых битов данных GPIO всегда вернет 0, запись в эти биты не дает никакого эффекта (на рисунках не используемые биты помечены серым цветом).
Регистры установки (GPIO set, PORTxIO_SET), сброса (GPIO clear, PORTxIO_CLEAR) и переключения (GPIO toggle, PORTxIO_TOGGLE) разрядов GPIO используются для побитного управления выходами GPIO. Этот механизм используется во избежание потенциальных проблем не традиционных не атомарных операций типа read-modify-write (прочитать-изменить-записать). Чтение этих регистров вернет состояние выводов GPIO. Чтение не используемых битов этих регистров всегда вернет 0, запись не оказывает никакого эффекта (не используемые биты на рисунках помечены серым цветом).
Рис. 15-13. GPIO Port C Set Register (PORTCIO_SET).
Рис. 15-14. GPIO Port D Set Register (PORTDIO_SET).
Рис. 15-15. GPIO Port E Set Register (PORTEIO_SET).
Рис. 15-16. GPIO Port C Clear Register (PORTCIO_CLEAR).
Рис. 15-17. GPIO Port D Clear Register (PORTDIO_CLEAR).
Рис. 15-18. GPIO Port E Clear Register (PORTEIO_CLEAR).
Рис. 15-19. GPIO Port C Toggle Register (PORTCIO_TOGGLE).
Рис. 15-20. GPIO Port D Toggle Register (PORTDIO_TOGGLE).
Рис. 15-21. GPIO Port E Toggle Register (PORTEIO_TOGGLE).
В качестве примера того, как работают эти регистры, предположим, что PD0 сконфигурирован как выход (PORTDIO_FER = 0x0001 и PORTDIO_DIR = 0x0001). Запись 0x0001 в регистр PORTDIO_SET переведет ножку выхода PD0 в состояние лог. 1 без влияния на состояние других выводов GPIO. Запись 0x0001 в регистр PORTDIO_CLEAR переведет выходной уровень вывода PD0 в состояние лог. 0 без влияния на состояние других выводов GPIO. Запись 0x0001 в регистр PORTDIO_TOGGLE поменяет состояние на выходе PD0 на противоположное от текущего состояния, без влияния на другие выводы GPIO.
Запись 0 в любой из этих регистров не оказывает никакого эффекта.
Чтение регистров PORTxIO_SET или PORTxIO_CLEAR возвратит следующее:
• 0 для выводов GPIO, которые настроены как выходы, и переведены в состояние лог. 0. • 1 для выводов GPIO, которые настроены как выходы, и переведены в состояние лог. 1. • Уровень входного сигнала для выводов GPIO, настроенных как входы (и у которых разрешены соответствующие входные буферы).
[Быстродействие / пропускная способность]
Выводы GPIO синхронизированы с системной тактовой частотой (SCLK). Когда выводы сконфигурированы как выходы, программируемые GPIO могут менять свое состояние на каждом перепаде системной тактовой частоты (не путайте с частотой ядра CCLK!).
Регистры процессора Blackfin, отображенные на адресное пространство памяти (memory-mapped registers, MMR) находятся в диапазоне адресов 0xFFE00000 .. 0xFFFFFFFF.
Ко всем MMR ядра доступ должен осуществляться как 32-битное чтение или запись.
В этом приложении перечислены адреса MMR ядра их имена. Чтобы получить больше информации про MMR, см. столбец "Подробнее в разделе".
Регистры GPIO port C, D, E (0xFFC0 1500 – 0xFFC0 15FF)
Таблица B-13. Регистры GPIO Port C.
Адрес MMR
Имя регистра
См. секцию
0xFFC0 1500
PORTCIO_FER
Регистр PORTxIO_FER
0xFFC0 1550
PORTCIO_DIR
Регистр PORTxIO_DIR
0xFFC0 1560
PORTCIO_INEN
Регистр PORTxIO_INEN
0xFFC0 1510
PORTCIO
Регистр PORTxIO
0xFFC0 1520
PORTCIO_CLEAR
Регистры PORTxIO_SET, PORTxIO_CLEAR и PORTxIO_TOGGLE
0xFFC0 1530
PORTCIO_SET
0xFFC0 1540
PORTCIO_TOGGLE
Таблица B-14. Регистры GPIO Port D.
Адрес MMR
Имя регистра
См. секцию
0xFFC0 1504
PORTDIO_FER
Регистр PORTxIO_FER
0xFFC0 1554
PORTDIO_DIR
Регистр PORTxIO_DIR
0xFFC0 1564
PORTDIO_INEN
Регистр PORTxIO_INEN
0xFFC0 1514
PORTDIO
Регистр PORTxIO
0xFFC0 1524
PORTDIO_CLEAR
Регистры PORTxIO_SET, PORTxIO_CLEAR и PORTxIO_TOGGLE
0xFFC0 1534
PORTDIO_SET
0xFFC0 1544
PORTDIO_TOGGLE
Таблица B-15. Регистры GPIO Port E.
Адрес MMR
Имя регистра
См. секцию
0xFFC0 1508
PORTEIO_FER
Регистр PORTxIO_FER
0xFFC0 1558
PORTEIO_DIR
Регистр PORTxIO_DIR
0xFFC0 1568
PORTEIO_INEN
Регистр PORTxIO_INEN
0xFFC0 1518
PORTEIO
Регистр PORTxIO
0xFFC0 1528
PORTEIO_CLEAR
Регистры PORTxIO_SET, PORTxIO_CLEAR и PORTxIO_TOGGLE
0xFFC0 1538
PORTEIO_SET
0xFFC0 1548
PORTEIO_TOGGLE
Регистры GPIO port F (0xFFC0 0700 – 0xFFC0 07FF)
Table B-16. Регистры GPIO Port F.
Адрес MMR
Имя регистра
См. секцию
0xFFC0 0700
PORTFIO_FLAG_D
Регистр PORTFIO
0xFFC0 0704
PORTEIO_FLAG_CLEAR
Регистры PORTFIO_SET, PORTFIO_CLEAR и PORTFIO_TOGGLE