GPIO
DS: Мощность привода (вход)
Этот вход включает режим повышенной мощности выходного драйвера (буфера). Повторюсь, включение режима повышенной прочности увеличивает опасность повреждения, поэтому будьте осторожны с этим режимом.
Множество триггеров D на схеме являются регистрами конфигурации для вывода. Они называются регистрами, потому что вы можете записать в них 0 или 1, и они сохранят это значение (технически, это триггеры, управляемые ребрами). Все эти регистры сопоставлены с памятью (у них есть адрес памяти и смещение в битах), и вы можете выполнять запись в них с помощью программного обеспечения. Вот что они делают:
{DS, PUE, OVAL, OE, IE}: Регистры блоков ввода-вывода для GPIO
Это драйверы для 5 входных линий блока ввода-вывода для его функции GPIO, как описано выше. Два почетных упоминания - OVAL и IVAL (не показаны на схеме). Чтобы записать состояние на выходной вывод, вам нужно записать это состояние в его OVAL регистр, а чтобы прочитать состояние входного вывода, вам нужно прочитать его регистр IVAL. Регистр IVAL записывается входной схемой, поэтому он доступен только для чтения.
IOF_EN: Включение аппаратной функции ввода-вывода
Селектор в середине схемы на самом деле является многострочным мультиплексором, который позволяет вам выбрать источник, который будет управлять входными линиями блока ввода-вывода (часто известный как pin-мультиплексирование). Этот селектор управляется регистром IOF_EN, который расшифровывается как включение аппаратной функции ввода-вывода.
Его значение по умолчанию равно 0, и это заставляет селектор использовать 5 триггеров в левом верхнем углу в качестве драйверов блока ввода-вывода. Это драйверы сигналов DS, PUE, OVAL, OE и IE для вывода, когда он настроен в режиме GPIO (IF_EN=0).
Когда оно равно 1, селектор будет использовать 5 сигналов, поступающих от селектора слева. Помните, что регистр IOF_EN включает аппаратную функцию ввода-вывода пина. Другими словами, операционный блок, который может управлять выводом в качестве альтернативной функции, будет управлять сигналами блока ввода-вывода (DS, PUE и остальными).
IOF_SEL: Выбор аппаратной функции ввода-вывода
Селектор слева выбирает один из двух возможных источников для 5 входных линий блока ввода-вывода. То есть, когда вы выбираете использовать альтернативную функцию для пина с его регистром IOF_EN равным 1, регистр IOF_SEL позволяет вам выбрать, какую из его 2 альтернативных функций использовать. Каждая из этих функций имеет свой собственный набор из 5 конфигурационных сигналов, точно так же, как регистры GPIO в верхнем левом углу, но в зависимости от операционного модуля (PWM, SPI, UART и т.д.), эти линии могут иметь регистры, или они могут использовать регистры GPIO. Не волнуйтесь, мы сделаем это в нескольких следующих примерах. Что касается входных сигналов, то, подобно приемным линиям в последовательной связи, сигнал IVAL используется через блок синхронизации. Нет необходимости что-либо мультиплексировать, потому что эти устройства будут просто прослушивать любой сигнал, находящийся в IVAL.
OUT_XOR: Инверсия выходного сигнала
Как GPIO, так и функции альтернативного вывода имеют возможность инвертировать выходные данные. Как вы, возможно, знаете, XOR-ворота справляются с этим довольно элегантно. Таким образом, регистр OUT_XOR управляет одним входом показанного элемента XOR, условно инвертируя состояние OVAL. Установка этого регистра инвертирует выходной сигнал, в то время как очистка этого регистра оставляет выходной сигнал таким, какой он есть.
Конфигурационные регистры
До этого момента все регистры, которые мы видели, были однобитными, но это не очень хорошо вписывается в архитектуру шины, подобную той, которую мы используем в аппаратном и программном обеспечении микроконтроллера. Вот почему разработчики микроконтроллеров обычно группируют эти однобитовые регистры в многоразрядные регистры. Вот некоторые конструктивные решения, касающиеся организации этих битов в регистрах, отображаемых в память.
Ширина регистра
Регистры конфигурации обычно имеют такой же размер, как и регистры архитектуры. Например:
Семейство микроконтроллеров s08 от NXP (первоначально Motorola) представляет собой 8-разрядную систему, поэтому ширина регистров конфигурации составляет 8 бит.
Семейство микроконтроллеров LPC11xx от NXP (первоначально Philips) использует процессор ARM Cortex, ширина которого составляет 32 бита, поэтому его регистры конфигурации также имеют ширину 32 бита (в этом случае обычно имеется много неиспользуемых битов).
Критерии группировки
В дополнение к группировке 1-разрядных регистров конфигурации микроконтроллеры различаются по способу группировки этих битов:
Семейство микроконтроллеров s08 группирует конфигурационные регистры по их функциям побитовым образом (используя смещение бита на вывод). Например, направление данных (ввод или вывод) для каждого вывода GPIO порта B контролируется регистром PTBDD, а тяговые резисторы для каждого вывода порта B управляются регистром PTBPE. Каждый бит в этих регистрах соответствует каждому выводу в порту GPIO. В регистре направления данных порта B (PTBDD) микроконтроллера s08 каждый бит соответствует каждому выводу в порту. Например, бит 3 (PTBDD3) определяет, является ли вывод 3 порта B входом или выходом.
Семейство микроконтроллеров LPC1100 группирует регистры конфигурации по выводу GPIO, к которому они принадлежат. Таким образом, если вам нужно работать с одним выводом ввода-вывода, вы можете работать с одним регистром. Все это находится в одном месте. Например, для порта 2, вывод 5, у вас есть все биты конфигурации в 32-разрядном регистре с именем IOCON_PIO2_5. Регистр конфигурации ввода/вывода для порта 2, вывод 5 (IOCON_PIO2_5) микроконтроллера LPC1114. Каждый бит соответствует другому аспекту конфигурации вывода 5 в порту 2.
Спецификация адреса
Чтобы получить доступ к этим регистрам, производители сопоставляют их с адресами памяти, и все эти адреса должны быть указаны в руководстве по эксплуатации микроконтроллера. Некоторые производители указывают адреса для каждого регистра конфигурации, в то время как другие просто указывают базовый адрес устройства и смещения для его регистров. Например:
В семействе микроконтроллеров s08 регистр направления данных для порта A (PAD) находится по адресу 0x0001, а регистр включения тягового резистора для порта A (PTAPE) расположен по адресу 0x1840. Предоставляется вся карта памяти целиком. Это правдоподобно, поскольку s08 имеет 16-разрядную адресную шину, поэтому адресуемое пространство составляет всего 64 кбайт.
В микроконтроллере LPC1114 базовый адрес блока конфигурации ввода-вывода равен 0x40044000, а регистр IOCON_PIO2_5 имеет смещение 0x44, поэтому его эффективный адрес равен 0x40044044 (база плюс смещение). Указаны только основания и смещения. Это имеет смысл, поскольку системы ARM Cortex-M имеют 32-разрядную адресную шину, поэтому адресуемое пространство составляет 4 Гб.
Конфигурационные регистры GPIO в микроконтроллере FE310
FE310 оснащен только одним устройством GPIO с 19 контактами, доступными пользователю. Все регистры конфигурации упакованы в блок, который начинается с базового адреса регистра 0x10012000, как показано в таблице 51 руководства пользователя:
![Экземпляры устройств GPIO в микроконтроллере FE310 (Взято с руководства пользователя FE310-G002, размещено с разрешения SiFive, Inc.)](/EDI/13_02_25_2/1739398847-5454/tutorial/1372/objects/4/files/03-04.jpg)
Рис. 3.4. Экземпляры устройств GPIO в микроконтроллере FE310 (Взято с руководства пользователя FE310-G002, размещено с разрешения SiFive, Inc.)
ngpio это ширина регистров конфигурации, поэтому, поскольку у нас доступно только 19 выводов, в этих регистрах много неиспользуемых битов.
Биты конфигурации сгруппированы по их функциям побитовым образом:
Каждый 32-разрядный регистр конфигурации расположен с определенным смещением. Эти смещения указаны в таблице 52 руководства пользователя:
![Смещения и описания регистров конфигурации GPIO (Взято с руководства пользователя FE310-G002, размещено с разрешения SiFive, Inc.)](/EDI/13_02_25_2/1739398847-5454/tutorial/1372/objects/4/files/03-06.jpg)
Рис. 3.6. Смещения и описания регистров конфигурации GPIO (Взято с руководства пользователя FE310-G002, размещено с разрешения SiFive, Inc.)
Имея только одно устройство GPIO с именем GPIO0 и базовым адресом 0x10012000, мы можем легко вычислить адрес каждого из его регистров конфигурации, просто добавив базовый адрес к смещению регистра. Например, output_en находится по адресу 0x10012008, а pue - по адресу 0x10012010.
На данный момент оборудования достаточно. В следующем разделе мы обсудим программное обеспечение.
GPIO в библиотеке Freedom Metal
Здесь мы познакомимся с библиотекой Freedom Metal в Freedom Studio. Для этого мы будем использовать проект Blinky, который мы только что создали.
Пожалуйста, обратите внимание: не позволяйте программному обеспечению напугать вас. Мы углубимся в код, чтобы узнать несколько подробностей о внутренней работе библиотеки Freedom Metal. Если в какой-то момент вы почувствуете, что мы заходим слишком далеко, пожалуйста, наберитесь терпения. Суть в том, что у вас будет доступ к библиотеке высокого уровня для настройки и использования всех модулей. Также обратите внимание, что вам не обязательно повторять следующий процесс. Вот почему она представлена вам сейчас.
Придерживаясь практического и экспериментального изучения библиотеки, давайте подтвердим логику OE-сигнала. Судя по схеме, вход OE в блок ввода-вывода имеет окружность, что означает инвертор. Тогда на управляющем входе буфера также есть эта окружность, предполагающая, что сигнал инвертирован дважды, поэтому он должен быть активным-высоким (значение 1 включает выходной буфер, а значение 0 отключает его). Но откуда мы знаем наверняка?
![Двойное отрицание в строке OE блока ввода-вывода (Взято с руководства пользователя FE310-G002, размещено с разрешения SiFive, Inc.)](/EDI/13_02_25_2/1739398847-5454/tutorial/1372/objects/4/files/03-07.jpg)
Рис. 3.7. Двойное отрицание в строке OE блока ввода-вывода (Взято с руководства пользователя FE310-G002, размещено с разрешения SiFive, Inc.)
Один из подходов заключается в изучении библиотеки, чтобы увидеть, что делает вызов функции metal_gpio_enable_output(led0, 5). Этот вызов функции находится в строке 58 hello.c (или рядом с ней). Перейдя к объявлению, вы найдете этот код в ./bsp/install/include/metal/gpio.h:
/*! * @brief Включить вывод на пин * @param gpio Дескриптор интерфейса GPIO * @param pin Номер пина проиндексированный начиная с 0 * @return 0 если вывод успешно включен */ __inline__ int metal_gpio_enable_output(struct metal_gpio *gpio, int pin){ if (!gpio) { return 1; } return gpio->vtable->enable_output(gpio, (1 << pin)); }