├── .gitattributes
├── .github
└── workflows
│ └── tg-send.yml
├── LICENSE
├── README.md
├── README_EN.md
├── examples
└── test
│ └── test.ino
├── keywords.txt
├── library.properties
└── src
├── GyverIO.h
├── GyverIO_SPI.h
├── gio
├── gio.h
├── gio_arduino.h
├── gio_avr.h
├── gio_defs.h
├── gio_esp32.h
└── gio_esp8266.h
└── utils
├── PinIO.h
├── PinT.h
├── shift.cpp
└── shift.h
/.gitattributes:
--------------------------------------------------------------------------------
1 | # Auto detect text files and perform LF normalization
2 | * text=auto
3 |
--------------------------------------------------------------------------------
/.github/workflows/tg-send.yml:
--------------------------------------------------------------------------------
1 |
2 | name: Telegram Message
3 | on:
4 | release:
5 | types: [published]
6 | jobs:
7 | build:
8 | name: Send Message
9 | runs-on: ubuntu-latest
10 | steps:
11 | - name: send telegram message on push
12 | uses: appleboy/telegram-action@master
13 | with:
14 | to: ${{ secrets.TELEGRAM_TO }}
15 | token: ${{ secrets.TELEGRAM_TOKEN }}
16 | disable_web_page_preview: true
17 | message: |
18 | ${{ github.event.repository.name }} v${{ github.event.release.tag_name }}
19 | ${{ github.event.release.body }}
20 | https://github.com/${{ github.repository }}
21 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2023 GyverLibs
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | [](https://github.com/GyverLibs/GyverIO/releases/latest/download/GyverIO.zip)
2 | [](https://registry.platformio.org/libraries/gyverlibs/GyverIO)
3 | [](https://alexgyver.ru/)
4 | [](https://alexgyver.ru/support_alex/)
5 | [](https://github-com.translate.goog/GyverLibs/GyverIO?_x_tr_sl=ru&_x_tr_tl=en)
6 |
7 | [](https://t.me/GyverLibs)
8 |
9 | # GyverIO
10 | Быстрые функции для работы с пинами AVR (полный список смотри в gio_avr.h), ESP8266, ESP32
11 | - Ускорение в среднем в 20-30 раз, итоговое время для всех архитектур практически одинаковое
12 | - Классы для быстрого управления пином
13 | - Отдельная обработка случаев константных и неконстантных пинов для AVR
14 | - Быстрая реализация функций shiftIn/shiftOut
15 | - Универсальный класс hard SPI / soft SPI для использования в библиотеках
16 |
17 | ## Скорость
18 | ### Условия измерения
19 | | | Версия | Частота |
20 | |---------|--------|---------|
21 | | AVR | 1.8.19 | 16 |
22 | | ESP8266 | 3.1.2 | 80 |
23 | | ESP32 | 2.0.11 | 240 |
24 | | ESP32C3 | 2.0.11 | 80 |
25 |
26 | ### GPIO (us)
27 | | | write NC | write | read NC | read | mode NC | mode |
28 | |--------------|----------|-------------|-----------|-------------|---------|-------------|
29 | | AVR Ardu | **5.3** | 5.3 | **4.8** | 4.8 | **3.3** | 3.3 |
30 | | AVR gio | 1.6 | ***0.125*** | 1.75 | ***0.075*** | 1.8 | ***0.125*** |
31 | | | | | | | | |
32 | | ESP8266 Ardu | **1.5** | 1.5 | **0.54** | 0.54 | **1.4** | 1.4 |
33 | | ESP8266 gio | 0.29 | ***0.08*** | 0.5 | ***0.17*** | 1.29 | ***0.58*** |
34 | | | | | | | | |
35 | | ESP32 Ardu | **0.33** | 0.33 | **0.124** | 0.124 | **16** | 16 |
36 | | ESP32 gio | 0.04 | ***0.04*** | 0.085 | ***0.085*** | 0.126 | ***0.08*** |
37 | | | | | | | | |
38 | | ESP32C3 Ardu | **0.91** | 0.91 | **0.25** | 0.25 | **21** | 21 |
39 | | ESP32C3 gio | 0.05 | ***0.05*** | 0.4 | ***0.08*** | 0.49 | ***0.08*** |
40 |
41 | > *NC* - пины не константы
42 |
43 | > **Жирным** выделено худшее время (Arduino не константы), ***жирным курсивом*** - лучшее (gio константы)
44 |
45 | ### Shift (MHz)
46 | | | shiftOut | gio::shift |
47 | |---------|----------|------------|
48 | | AVR NC | 0.06 | 0.66 |
49 | | AVR | 0.06 | 1.3 |
50 | | ESP8266 | 0.2 | 1.1 |
51 | | ESP32 | 0.96 | 6 |
52 | | ESP32C3 | 0.35 | 2.6 |
53 |
54 | > *NC* - пины не константы
55 |
56 | ### Совместимость
57 | Совместима со всеми Arduino платформами (используются Arduino-функции)
58 | - Для esp8266 и esp32 быстрый `pinMode()` (`mode()`) работает только на режимы `INPUT`/`OUTPUT`! В остальных режимах вызывается штатный `pinMode()`
59 |
60 | ## Содержание
61 | - [Документация](#docs)
62 | - [Использование](#usage)
63 | - [Версии](#versions)
64 | - [Установка](#install)
65 | - [Баги и обратная связь](#feedback)
66 |
67 |
68 | ## Документация
69 | ### gio
70 | Быстые функции для работы с пинами
71 |
72 | ```cpp
73 | int gio::read(int P);
74 | void gio::high(int P);
75 | void gio::low(int P)
76 | void gio::write(int P, int V);
77 |
78 | //
79 | void gio::toggle(int P);
80 |
81 | // режим пина. Для esp8266/esp32 только INPUT/OUTPUT!
82 | void gio::mode(int P, int V);
83 |
84 | // нужно вызывать для esp8266/esp32 при инициализации пина
85 | // иначе mode() не будет работать!
86 | void gio::init(int P);
87 | ```
88 | > У esp8266/esp32 нужно обязательно вызвать `gio::init` перед использованием!
89 |
90 | ### gio::shift
91 | Быстрый аналог shiftIn/shiftOut (отправка данных с клоком)
92 |
93 | ```cpp
94 | // прочитать пакет. Вернёт true, если хотя бы один бит отличается
95 | bool gio::shift::read(uint8_t dat_pin, uint8_t clk_pin, uint8_t order, uint8_t* data, uint16_t len, uint8_t delay = 0);
96 |
97 | // прочитать байт
98 | uint8_t gio::shift::read_byte(uint8_t dat_pin, uint8_t clk_pin, uint8_t order, uint8_t delay = 0);
99 |
100 | // прочитать пакет + cs пин. Вернёт true, если хотя бы один бит отличается
101 | bool gio::shift::read_cs(uint8_t dat_pin, uint8_t clk_pin, uint8_t cs_pin, uint8_t order, uint8_t* data, uint16_t len, uint8_t delay = 0);
102 |
103 | // прочитать байт + cs пин
104 | uint8_t gio::shift::read_cs_byte(uint8_t dat_pin, uint8_t clk_pin, uint8_t cs_pin, uint8_t order, uint8_t delay = 0);
105 |
106 | // отправить пакет
107 | void gio::shift::send(uint8_t dat_pin, uint8_t clk_pin, uint8_t order, uint8_t* data, uint16_t len, uint8_t delay = 0);
108 |
109 | // отправить байт
110 | void gio::shift::send_byte(uint8_t dat_pin, uint8_t clk_pin, uint8_t order, uint8_t data, uint8_t delay = 0);
111 |
112 | // отправить пакет + cs пин
113 | void gio::shift::send_cs(uint8_t dat_pin, uint8_t clk_pin, uint8_t cs_pin, uint8_t order, uint8_t* data, uint16_t len, uint8_t delay = 0);
114 |
115 | // отправить байт + cs пин
116 | void gio::shift::send_cs_byte(uint8_t dat_pin, uint8_t clk_pin, uint8_t cs_pin, uint8_t order, uint8_t data, uint8_t delay = 0);
117 | ```
118 |
119 | Параметр `order` может быть:
120 | - `LSBFIRST`/`LSB_NORMAL` - LSB, прямой порядок байтов
121 | - `MSBFIRST`/`MSB_NORMAL` - MSB, прямой порядок байтов
122 | - `LSB_REVERSE` - LSB, обратный порядок байтов
123 | - `MSB_REVERSE` - MSB, обратный порядок байтов
124 |
125 | #### Примечание
126 | - `delay` в микросекундах, позволяет уменьшить скорость передачи. Например `1` мкс ограничит скорость до ~1 МГц, 2 мкс до ~500 кГц
127 | - Пины нужно сконфигурировать как `OUTPUT` самостоятельно до отправки (при запуске программы например)
128 |
129 | ### gio::SSPI
130 | Универсальный класс программно-аппаратного SPI с оптимизацией количества переменных для пинов
131 |
132 | ```cpp
133 | SSPI<0, freq> spi; // аппаратный без пина CS
134 | SSPI<0, freq, cs> spi; // аппаратный с пином CS в шаблоне
135 | SSPI<0, freq> spi(cs); // аппаратный с пином CS в классе
136 | SSPI<1, freq, cs, dt, clk> spi; // программный с пинами в шаблоне
137 | SSPI<1, freq> spi(cs, dt, clk); // программный с пинами в классе
138 | ```
139 |
140 | ### Настройки компиляции
141 | ```cpp
142 | #define GIO_USE_ARDUINO // отключить быстрые функции (заменить на стандартные)
143 | #define GIO_NO_MASK // отключить быстрый IO на основе маски для AVR (в классе PinIO и всех shift)
144 | ```
145 |
146 |
147 | ## Использование
148 |
149 | ```cpp
150 | #include
151 |
152 | gio::write(3, 1); // включить пин 3
153 |
154 | // отправить данные по пинам 3 и 4
155 | uint8_t data[] = {34, 63, 231, 9};
156 | gio::shift::send(3, 4, MSBFIRST, data, 4);
157 |
158 | SSPI<0, f, cs> spi;
159 | spi.send(0x12);
160 | ```
161 |
162 |
163 | ## Версии
164 | - v1.0
165 | - v1.1 - в 3 раза ускорен AVR non-const, обновлены таблицы
166 | - v1.2 - исправлена ошибка!
167 | - v1.2.1 - небольшая оптимизация
168 | - v1.2.2 - добавлена инверсия в shift
169 | - v1.2.4 - исправлен баг в gio::shift::read для AVR NC
170 | - v1.2.5 - добавлен возврат true в gio::shift::read при изменении буфера
171 | - v1.3.0 - исправлена критическая ошибка AVR/mode/NC
172 | - v1.3.1 - добавлен дополнительный delay в shift для симметричности клока
173 | - v1.3.2 - SSPI вынесен в отдельный файл, чтобы не мешать компиляции на некоторых платформах
174 | - v1.3.4 - поддержка ESP32C6
175 |
176 |
177 | ## Установка
178 | - Библиотеку можно найти по названию **GyverIO** и установить через менеджер библиотек в:
179 | - Arduino IDE
180 | - Arduino IDE v2
181 | - PlatformIO
182 | - [Скачать библиотеку](https://github.com/GyverLibs/GyverIO/archive/refs/heads/main.zip) .zip архивом для ручной установки:
183 | - Распаковать и положить в *C:\Program Files (x86)\Arduino\libraries* (Windows x64)
184 | - Распаковать и положить в *C:\Program Files\Arduino\libraries* (Windows x32)
185 | - Распаковать и положить в *Документы/Arduino/libraries/*
186 | - (Arduino IDE) автоматическая установка из .zip: *Скетч/Подключить библиотеку/Добавить .ZIP библиотеку…* и указать скачанный архив
187 | - Читай более подробную инструкцию по установке библиотек [здесь](https://alexgyver.ru/arduino-first/#%D0%A3%D1%81%D1%82%D0%B0%D0%BD%D0%BE%D0%B2%D0%BA%D0%B0_%D0%B1%D0%B8%D0%B1%D0%BB%D0%B8%D0%BE%D1%82%D0%B5%D0%BA)
188 | ### Обновление
189 | - Рекомендую всегда обновлять библиотеку: в новых версиях исправляются ошибки и баги, а также проводится оптимизация и добавляются новые фичи
190 | - Через менеджер библиотек IDE: найти библиотеку как при установке и нажать "Обновить"
191 | - Вручную: **удалить папку со старой версией**, а затем положить на её место новую. "Замену" делать нельзя: иногда в новых версиях удаляются файлы, которые останутся при замене и могут привести к ошибкам!
192 |
193 |
194 | ## Баги и обратная связь
195 | При нахождении багов создавайте **Issue**, а лучше сразу пишите на почту [alex@alexgyver.ru](mailto:alex@alexgyver.ru)
196 | Библиотека открыта для доработки и ваших **Pull Request**'ов!
197 |
198 | При сообщении о багах или некорректной работе библиотеки нужно обязательно указывать:
199 | - Версия библиотеки
200 | - Какой используется МК
201 | - Версия SDK (для ESP)
202 | - Версия Arduino IDE
203 | - Корректно ли работают ли встроенные примеры, в которых используются функции и конструкции, приводящие к багу в вашем коде
204 | - Какой код загружался, какая работа от него ожидалась и как он работает в реальности
205 | - В идеале приложить минимальный код, в котором наблюдается баг. Не полотно из тысячи строк, а минимальный код
206 |
--------------------------------------------------------------------------------
/README_EN.md:
--------------------------------------------------------------------------------
1 | This is an automatic translation, may be incorrect in some places. See sources and examples!
2 |
3 | # Gyverio
4 | Fast functions for working with AVR Pin (a full list look at Gio_avr.h), ESP8266, ESP32
5 | - acceleration on average by 20-30 times, the final time for all architectures is almost the same
6 | - Classes for quick PIN control
7 | - Separate processing of cases of constant and uncontrolled pins for AVR
8 | - Fast implementation of Shiftin/Shiftout
9 | - Universal class Hard Spi / Soft SPI for use in libraries
10 |
11 | ## Speed
12 | ### measurement conditions
13 | ||Version |Frequency |
14 | | --------- | -------- | -------- |
15 | |AVR |1.8.19 |16 |
16 | |ESP8266 |3.1.2 |80 |
17 | |ESP32 |2.0.11 |240 |
18 | |ESP32C3 |2.0.11 |80 |
19 |
20 | ### GPIO (US)
21 | ||Write NC |Write |Read NC |Read |Mode NC |Mode |
22 | | ------------- | ---------- | ----------------- | ------------------------------| ------------ | --------- | ------------
23 | |AVR Ardu |** 5.3 ** |5.3 |** 4.8 ** |4.8 |** 3.3 ** |3.3 |
24 | |AVR Gio |1.6 |*** 0.125 *** |1.75 |*** 0.075 *** |1.8 |*** 0.125 *** |
25 | ||||||||
26 | |ESP8266 Ardu |** 1.5 ** |1.5 |** 0.54 ** |0.54 |** 1.4 ** |1.4 |
27 | |ESP8266 Gio |0.29 |*** 0.08 *** |0.5 |*** 0.17 *** |1.29 |*** 0.58 *** |
28 | ||||||||
29 | |ESP32 Ardu |** 0.33 ** |0.33 |** 0.124 ** |0.124 |** 16 ** |16 |
30 | |ESP32 Gio |0.04 |*** 0.04 *** |0.085 |*** 0.085 *** |0.126 |*** 0.08 *** |
31 | ||||||||
32 | |ESP32C3 Ardu |** 0.91 ** |0.91 |** 0.25 ** |0.25 |** 21 ** |21 |
33 | |ESP32C3 Gio |0.05 |*** 0.05 *** |0.4 |*** 0.08 *** |0.49 |*** 0.08 *** |
34 |
35 | > * Nc * - Pins are not constants
36 |
37 | > ** Fat ** highlighted the worst time (Arduino not constants), *** with a fat italics *** - the best (gio constants)
38 |
39 | ### Shift (MHZ)
40 | ||Shiftout |Gio :: Shift |
41 | | -------- | ---------- | -----------------------------------
42 | |AVR NC |0.06 |0.66 |
43 | |AVR |0.06 |1.3 |
44 | |ESP8266 |0.2 |1.1 |
45 | |ESP32 |0.96 |6 |
46 | |ESP32C3 |0.35 |2.6 |
47 |
48 | > * Nc * - Pins are not constants
49 |
50 | ## compatibility
51 | Compatible with all arduino platforms (used arduino functions)
52 | - For ESP8266 and ESP32, fast `pinmode ()` (`mode ()`) works only on `Input`/` output`!In other modes, the standard `pinmode ()` is called
53 |
54 | ## Content
55 | - [documentation] (#docs)
56 | - [use] (#usage)
57 | - [versions] (#varsions)
58 | - [installation] (# Install)
59 | - [bugs and feedback] (#fedback)
60 |
61 |
62 | ## Documentation
63 | ## Gio
64 | Squeezing pins
65 |
66 | `` `CPP
67 | int Gio :: read (int p);
68 | Void Gio :: High (int p);
69 | Void Gio :: Low (int p)
70 | Void Gio :: Write (int p, int v);
71 |
72 | //
73 | Void Gio :: Toggle (int p);
74 |
75 | // Pin mode.For ESP8266/ESP32 only Input/Output!
76 | Void Gio :: Mode (int p, int v);
77 |
78 | // you need to call for ESP8266/ESP32 when initializing the PIN
79 | // Otherwise, mod () will not work!
80 | Void Gio :: Init (int p);
81 | `` `
82 |
83 | ### Gio :: Shift
84 | Fast analogue Shiftin/Shiftout (sending data with a clock)
85 |
86 | `` `CPP
87 | // Read the package
88 | vOID GIO :: Shift :: Read (uint8_t data_pin, uint8_t clk_pin, uint8_t Order, uint8_t* Data, Uint16_t Len, Uint8_t Delay = 0);
89 |
90 | // Read the byte
91 | uint8_t Gio :: Shift :: read_byte (uint8_t dat_pin, uint8_t clak_pin, uint8_t Order, uint8_t demely = 0);
92 |
93 | // Read the package + cs pin
94 | VOID GIO :: Shift :: Read_cs (uint8_t data_pin, uint8_t clk_pin, uint8_t cs_pin, uint8_t Order, uint8_t* data, uint16_t Len, uint8_t Delay = 0);
95 |
96 | // read byte + cs pin
97 | Uint8_t Gio :: Shift :: Read_cs_byte (uint8_t data_pin, uint8_t clk_pin, uint8_t cs_pin, uint8_t order, uint8_t dlavay = 0);
98 |
99 | // Send a package
100 | VOID Gio :: Shift :: Send (uint8_t data_pin, uint8_t clk_pin, uint8_t Order, uint8_t* data, uint16_t len, uint8_t dlavay = 0);
101 |
102 | // Send byte
103 | VOID Gio :: Shift :: Send_byte (uint8_t data_pin, uint8_t clk_pin, uint8_t order, uint8_t data, uint8_t demelavy = 0);
104 |
105 | // Send package + cs pin
106 | VOID Gio :: Shift :: Send_cs (uint8_t data_pin, uint8_t clk_pin, uint8_t cs_pin, uint8_t Order, uint8_t* data, uint16_t Len, uint8_t demelavy = 0);
107 |
108 | // Send byte + cs pin
109 | VOID GIO :: Shift :: Send_cs_byte (uint8_t data_pin, uint8_t clk_pin, uint8_t cs_pin, uint8_t ORDER, UINT8_T DATA, UINT8_T DELAY = 0);
110 | `` `
111 |
112 | The `order` parameter can be:
113 | - `lsbfirst`/` lsb_normal` - lsb, direct bytes directly
114 | - `MSBFIRST`/` MSB_Normal` - MSB, direct bytes direct
115 | - `lsb_reverse` - lsb, reverse byte order
116 | - `MSB_Reverse` - MSB, reverse bytes
117 |
118 | #### Note
119 | - `Delay` in microseconds, allows you to reduce the speed of transmission.For example, `1` μs will limit speed up to ~ 1 MHz, 2 μs up to ~ 500 kHz
120 | - Pins should be configured as `output` yourself before sending (when starting a program for example)
121 |
122 | ### Gio :: SSPI
123 | Universal class of software and hardware SPI with optimization of the number of variables for Pin
124 |
125 | `` `CPP
126 | SSPI <0, Freq> Spi;// hardware without PIN CS
127 | SSPI <0, Freq, CS> SPI;// Hardware with PIN CS in the template
128 | SSPI <0, Freq> Spi (CS);// Hardware with PIN CS in the classroom
129 | SSPI <1, Freq, CS, DT, CLK> Spi;// Program with pines in the template
130 | SSPI <1, FreQ> Spi (CS, DT, CLK);// Program with pins in class
131 | `` `
132 |
133 | ### compilation settings
134 | `` `CPP
135 | #define gio_use_arduino // Disable quick functions (replace with standard)
136 | #define gio_no_mask // Disable a quick IO based on AVR mask (in the Pinio class and all Shift)
137 | `` `
138 |
139 |
140 | ## Usage
141 |
142 | `` `CPP
143 | Gio :: Write (3, 1);// Turn on PIN 3
144 |
145 | // Send data on pins 3 and 4
146 | uint8_t data [] = {34, 63, 231, 9};
147 | Gio :: Shift :: Send (3, 4, MSBFIRST, DATA, 4);
148 | `` `
149 |
150 |
151 | ## versions
152 | - V1.0
153 | - V1.1 - AVR Non -Const is 3 times accelerated, the tables are updated
154 | - V1.2 - Fixed a mistake!
155 | - V1.2.1 - Small optimization
156 | - v1.2.2 - added inversion to Shift
157 |
158 |
159 | ## Installation
160 | - The library can be found by the name ** gyverio ** and installed through the library manager in:
161 | - Arduino ide
162 | - Arduino ide v2
163 | - Platformio
164 | - [download the library] (https://github.com/gyverlibs/gyverio/archive/refs/heads/main.zip) .Zip archive for manual installation:
165 | - unpack and put in * C: \ Program Files (X86) \ Arduino \ Libraries * (Windows X64)
166 | - unpack and put in * C: \ Program Files \ Arduino \ Libraries * (Windows X32)
167 | - unpack and put in *documents/arduino/libraries/ *
168 | - (Arduino id) Automatic installation from. Zip: * sketch/connect the library/add .Zip library ... * and specify downloaded archive
169 | - Read more detailed instructions for installing libraries [here] (https://alexgyver.ru/arduino-first/#%D0%A3%D1%81%D1%82%D0%B0%BD%D0%BE%BE%BE%BED0%B2%D0%BA%D0%B0_%D0%B1%D0%B8%D0%B1%D0%BB%D0%B8%D0%BE%D1%82%D0%B5%D0%BA)
170 | ### Update
171 | - I recommend always updating the library: errors and bugs are corrected in the new versions, as well as optimization and new features are added
172 | - through the IDE library manager: find the library how to install and click "update"
173 | - Manually: ** remove the folder with the old version **, and then put a new one in its place.“Replacement” cannot be done: sometimes files are deleted in new versions,Cranberries that remain when replacing and can lead to errors!
174 |
175 |
176 | ## bugs and feedback
177 | Create ** Issue ** when you find the bugs, and better immediately write to the mail [alex@alexgyver.ru] (mailto: alex@alexgyver.ru)
178 | The library is open for refinement and your ** pull Request ** 'ow!
179 |
180 | When reporting about bugs or incorrect work of the library, it is necessary to indicate:
181 | - The version of the library
182 | - What is MK used
183 | - SDK version (for ESP)
184 | - version of Arduino ide
185 | - whether the built -in examples work correctly, in which the functions and designs are used, leading to a bug in your code
186 | - what code has been loaded, what work was expected from it and how it works in reality
187 | - Ideally, attach the minimum code in which the bug is observed.Not a canvas of a thousand lines, but a minimum code
--------------------------------------------------------------------------------
/examples/test/test.ino:
--------------------------------------------------------------------------------
1 | #include
2 |
3 | #include "GyverIO.h"
4 |
5 | // gio::SSPI spi0;
6 | // gio::SSPI spi1;
7 | // gio::SSPI spi2(9);
8 | // gio::SSPI spi3;
9 | // gio::SSPI spi4(9, 11, 13);
10 |
11 | #define PIN_DAT 7
12 | #define PIN_CLK 6
13 | byte datNC, clkNC;
14 |
15 | void setup() {
16 | pinMode(PIN_DAT, OUTPUT);
17 | pinMode(PIN_CLK, OUTPUT);
18 | // gio::shift::send_byte(PIN_DAT, PIN_CLK, MSBFIRST, 0b10100101);
19 | }
20 |
21 | void loop() {
22 | datNC = digitalRead(5);
23 | clkNC = digitalRead(5);
24 | datNC = PIN_DAT;
25 | clkNC = PIN_CLK;
26 | digitalWrite(PIN_DAT, 1);
27 | delayMicroseconds(50);
28 | digitalWrite(PIN_DAT, 0);
29 | delayMicroseconds(50);
30 | noInterrupts();
31 |
32 | shiftOut(datNC, clkNC, MSBFIRST, 0b10100101);
33 | shiftOut(PIN_DAT, PIN_CLK, MSBFIRST, 0b10100101);
34 | gio::shift::send_byte(datNC, clkNC, MSBFIRST, 0b10100101);
35 | gio::shift::send_byte(PIN_DAT, PIN_CLK, MSBFIRST, 0b10100101);
36 | delayMicroseconds(50);
37 |
38 | // ardu write nc
39 | digitalWrite(datNC, 1);
40 | digitalWrite(datNC, 0);
41 | digitalWrite(datNC, 1);
42 | digitalWrite(datNC, 0);
43 | digitalWrite(datNC, 1);
44 | digitalWrite(datNC, 0);
45 | digitalWrite(datNC, 1);
46 | digitalWrite(datNC, 0);
47 | digitalWrite(datNC, 1);
48 | digitalWrite(datNC, 0);
49 | delayMicroseconds(10);
50 |
51 | // ardu write
52 | digitalWrite(PIN_DAT, 1);
53 | digitalWrite(PIN_DAT, 0);
54 | digitalWrite(PIN_DAT, 1);
55 | digitalWrite(PIN_DAT, 0);
56 | digitalWrite(PIN_DAT, 1);
57 | digitalWrite(PIN_DAT, 0);
58 | digitalWrite(PIN_DAT, 1);
59 | digitalWrite(PIN_DAT, 0);
60 | digitalWrite(PIN_DAT, 1);
61 | digitalWrite(PIN_DAT, 0);
62 | delayMicroseconds(10);
63 |
64 | // ardu read nc
65 | gio::write(PIN_DAT, 1);
66 | gio::write(PIN_DAT, 0);
67 | gio::write(PIN_DAT, 1);
68 | gio::write(PIN_DAT, 0);
69 | gio::write(PIN_DAT, 1);
70 |
71 | digitalRead(datNC);
72 |
73 | gio::write(PIN_DAT, 0);
74 | gio::write(PIN_DAT, 1);
75 | gio::write(PIN_DAT, 0);
76 | gio::write(PIN_DAT, 1);
77 | gio::write(PIN_DAT, 0);
78 | delayMicroseconds(10);
79 |
80 | // ardu read
81 | gio::write(PIN_DAT, 1);
82 | gio::write(PIN_DAT, 0);
83 | gio::write(PIN_DAT, 1);
84 | gio::write(PIN_DAT, 0);
85 | gio::write(PIN_DAT, 1);
86 |
87 | digitalRead(PIN_DAT);
88 |
89 | gio::write(PIN_DAT, 0);
90 | gio::write(PIN_DAT, 1);
91 | gio::write(PIN_DAT, 0);
92 | gio::write(PIN_DAT, 1);
93 | gio::write(PIN_DAT, 0);
94 | delayMicroseconds(10);
95 |
96 | // ardu mode nc
97 | gio::write(PIN_DAT, 1);
98 | gio::write(PIN_DAT, 0);
99 | gio::write(PIN_DAT, 1);
100 | gio::write(PIN_DAT, 0);
101 | gio::write(PIN_DAT, 1);
102 |
103 | pinMode(datNC, OUTPUT);
104 |
105 | gio::write(PIN_DAT, 0);
106 | gio::write(PIN_DAT, 1);
107 | gio::write(PIN_DAT, 0);
108 | gio::write(PIN_DAT, 1);
109 | gio::write(PIN_DAT, 0);
110 | delayMicroseconds(10);
111 |
112 | // ardu mode
113 | gio::write(PIN_DAT, 1);
114 | gio::write(PIN_DAT, 0);
115 | gio::write(PIN_DAT, 1);
116 | gio::write(PIN_DAT, 0);
117 | gio::write(PIN_DAT, 1);
118 |
119 | pinMode(PIN_DAT, OUTPUT);
120 |
121 | gio::write(PIN_DAT, 0);
122 | gio::write(PIN_DAT, 1);
123 | gio::write(PIN_DAT, 0);
124 | gio::write(PIN_DAT, 1);
125 | gio::write(PIN_DAT, 0);
126 | delayMicroseconds(50);
127 |
128 | // gio write nc
129 | gio::write(datNC, 1);
130 | gio::write(datNC, 0);
131 | gio::write(datNC, 1);
132 | gio::write(datNC, 0);
133 | gio::write(datNC, 1);
134 | gio::write(datNC, 0);
135 | gio::write(datNC, 1);
136 | gio::write(datNC, 0);
137 | gio::write(datNC, 1);
138 | gio::write(datNC, 0);
139 | delayMicroseconds(10);
140 |
141 | // gio write
142 | gio::write(PIN_DAT, 1);
143 | gio::write(PIN_DAT, 0);
144 | gio::write(PIN_DAT, 1);
145 | gio::write(PIN_DAT, 0);
146 | gio::write(PIN_DAT, 1);
147 | gio::write(PIN_DAT, 0);
148 | gio::write(PIN_DAT, 1);
149 | gio::write(PIN_DAT, 0);
150 | gio::write(PIN_DAT, 1);
151 | gio::write(PIN_DAT, 0);
152 | delayMicroseconds(10);
153 |
154 | // gio read nc
155 | gio::write(PIN_DAT, 1);
156 | gio::write(PIN_DAT, 0);
157 | gio::write(PIN_DAT, 1);
158 | gio::write(PIN_DAT, 0);
159 | gio::write(PIN_DAT, 1);
160 |
161 | gio::read(datNC);
162 |
163 | gio::write(PIN_DAT, 0);
164 | gio::write(PIN_DAT, 1);
165 | gio::write(PIN_DAT, 0);
166 | gio::write(PIN_DAT, 1);
167 | gio::write(PIN_DAT, 0);
168 | delayMicroseconds(10);
169 |
170 | // gio read
171 | gio::write(PIN_DAT, 1);
172 | gio::write(PIN_DAT, 0);
173 | gio::write(PIN_DAT, 1);
174 | gio::write(PIN_DAT, 0);
175 | gio::write(PIN_DAT, 1);
176 |
177 | gio::read(PIN_DAT);
178 |
179 | gio::write(PIN_DAT, 0);
180 | gio::write(PIN_DAT, 1);
181 | gio::write(PIN_DAT, 0);
182 | gio::write(PIN_DAT, 1);
183 | gio::write(PIN_DAT, 0);
184 | delayMicroseconds(10);
185 |
186 | // gio mode nc
187 | gio::write(PIN_DAT, 1);
188 | gio::write(PIN_DAT, 0);
189 | gio::write(PIN_DAT, 1);
190 | gio::write(PIN_DAT, 0);
191 | gio::write(PIN_DAT, 1);
192 |
193 | gio::mode(datNC, OUTPUT);
194 |
195 | gio::write(PIN_DAT, 0);
196 | gio::write(PIN_DAT, 1);
197 | gio::write(PIN_DAT, 0);
198 | gio::write(PIN_DAT, 1);
199 | gio::write(PIN_DAT, 0);
200 | delayMicroseconds(10);
201 |
202 | // gio mode
203 | gio::write(PIN_DAT, 1);
204 | gio::write(PIN_DAT, 0);
205 | gio::write(PIN_DAT, 1);
206 | gio::write(PIN_DAT, 0);
207 | gio::write(PIN_DAT, 1);
208 |
209 | gio::mode(PIN_DAT, OUTPUT);
210 |
211 | gio::write(PIN_DAT, 0);
212 | gio::write(PIN_DAT, 1);
213 | gio::write(PIN_DAT, 0);
214 | gio::write(PIN_DAT, 1);
215 | gio::write(PIN_DAT, 0);
216 | delayMicroseconds(10);
217 |
218 | interrupts();
219 | }
--------------------------------------------------------------------------------
/keywords.txt:
--------------------------------------------------------------------------------
1 | #######################################
2 | # Syntax Coloring Map For GyverIO
3 | #######################################
4 |
5 | #######################################
6 | # Datatypes (KEYWORD1)
7 | #######################################
8 |
9 | GyverIO KEYWORD1
10 | Pin KEYWORD1
11 | PinIO KEYWORD1
12 | PinT KEYWORD1
13 | SSPI KEYWORD1
14 |
15 | GIO_USE_ARDUINO KEYWORD1
16 | GIO_NO_MASK KEYWORD1
17 |
18 | #######################################
19 | # Methods and Functions (KEYWORD2)
20 | #######################################
21 |
22 | init KEYWORD2
23 | toggle KEYWORD2
24 | write KEYWORD2
25 | high KEYWORD2
26 | low KEYWORD2
27 | read KEYWORD2
28 | mode KEYWORD2
29 |
30 | read KEYWORD2
31 | read_byte KEYWORD2
32 | read_cs KEYWORD2
33 | read_cs_byte KEYWORD2
34 | send KEYWORD2
35 | send_byte KEYWORD2
36 | send_cs KEYWORD2
37 | send_cs_byte KEYWORD2
38 |
39 | #######################################
40 | # Constants (LITERAL1)
41 | #######################################
42 |
43 | gio LITERAL1
44 | shift LITERAL1
45 | LSB_NORMAL LITERAL1
46 | MSB_NORMAL LITERAL1
47 | LSB_REVERSE LITERAL1
48 | MSB_REVERSE LITERAL1
--------------------------------------------------------------------------------
/library.properties:
--------------------------------------------------------------------------------
1 | name=GyverIO
2 | version=1.3.11
3 | author=AlexGyver
4 | maintainer=AlexGyver
5 | sentence=Fast GPIO operation functions for AVR, ESP8266, ESP32
6 | paragraph=Fast GPIO operation functions for AVR, ESP8266, ESP32
7 | category=Signal Input/Output
8 | url=https://github.com/GyverLibs/GyverIO
9 | architectures=*
--------------------------------------------------------------------------------
/src/GyverIO.h:
--------------------------------------------------------------------------------
1 | #pragma once
2 |
3 | #include "gio/gio.h"
4 | #include "utils/PinIO.h"
5 | #include "utils/PinT.h"
6 | #include "utils/shift.h"
--------------------------------------------------------------------------------
/src/GyverIO_SPI.h:
--------------------------------------------------------------------------------
1 | #pragma once
2 |
3 | #include
4 | #include
5 |
6 | #include "utils/shift.h"
7 |
8 | namespace gio {
9 |
10 | template
11 | class SSPI {
12 | public:
13 | SSPI(int8_t cs = -1, int8_t dat = -1, int8_t clk = -1) {
14 | if (_softT) {
15 | if (_datT >= 0) {
16 | gio::init(_datT, OUTPUT);
17 | gio::init(_clkT, OUTPUT);
18 | } else {
19 | _pins[1] = dat;
20 | _pins[2] = clk;
21 | gio::init(_pins[1], OUTPUT);
22 | gio::init(_pins[2], OUTPUT);
23 | }
24 | }
25 |
26 | if (_csT >= 0) {
27 | gio::init(_csT, OUTPUT);
28 | gio::high(_csT);
29 | } else {
30 | _pins[0] = cs;
31 | if (cs >= 0) {
32 | gio::init(cs, OUTPUT);
33 | gio::high(cs);
34 | }
35 | }
36 | }
37 | void send(uint8_t data) {
38 | _begin();
39 | if (_softT) {
40 | if (_datT >= 0) gio::shift::send_byte(_datT, _clkT, MSBFIRST, data, 1000000ul / _freqT);
41 | else gio::shift::send_byte(_pins[1], _pins[2], MSBFIRST, data, 1000000ul / _freqT);
42 | } else {
43 | SPI.transfer(data);
44 | }
45 | _end();
46 | }
47 | void send(uint8_t* data, uint16_t len) {
48 | _begin();
49 | if (_softT) {
50 | if (_datT >= 0) gio::shift::send(_datT, _clkT, MSBFIRST, data, len, 1000000ul / _freqT);
51 | else gio::shift::send(_pins[1], _pins[2], MSBFIRST, data, len, 1000000ul / _freqT);
52 | } else {
53 | for (uint16_t i = 0; i < len; i++) SPI.transfer(data[i]);
54 | }
55 | _end();
56 | }
57 |
58 | private:
59 | void _begin() {
60 | if (_csT >= 0) gio::low(_csT);
61 | else if (_pins[0] >= 0) gio::low(_pins[0]);
62 |
63 | if (!_softT) SPI.beginTransaction(SPISettings(_freqT, MSBFIRST, SPI_MODE0));
64 | }
65 | void _end() {
66 | if (!_softT) SPI.endTransaction();
67 |
68 | if (_csT >= 0) gio::high(_csT);
69 | else if (_pins[0] >= 0) gio::high(_pins[0]);
70 | }
71 |
72 | int8_t _pins[(_csT < 0) + ((_softT && _datT < 0) ? 2 : 0)]; // CS, DAT, CLK
73 |
74 | /*
75 | SSPI<0, f, cs> spi; 0
76 | SSPI<0, f, -1> spi(?); 1
77 | SSPI<1, f, cs, dat, clk> spi; 0
78 | SSPI<1, f> spi(cs, dat, clk); 1+2
79 | */
80 | };
81 |
82 | } // namespace gio
--------------------------------------------------------------------------------
/src/gio/gio.h:
--------------------------------------------------------------------------------
1 | #pragma once
2 | // быстрые функции пинов
3 | // #define GIO_USE_ARDUINO
4 |
5 | #ifdef GIO_USE_ARDUINO
6 | #include "gio_arduino.h"
7 | #else
8 |
9 | #if defined(__AVR__) || defined(ARDUINO_ARCH_AVR)
10 | #include "gio_avr.h"
11 | #elif defined(ESP8266) || defined(ARDUINO_ARCH_ESP8266)
12 | #include "gio_esp8266.h"
13 | #elif defined(ESP32) || defined(ARDUINO_ARCH_ESP32)
14 | #include "gio_esp32.h"
15 | #else
16 | #include "gio_arduino.h"
17 | #endif
18 |
19 | #endif // GIO_USE_ARDUINO
20 |
21 | /*
22 | us (MHz)
23 | | | digitalWrite | gio_write | gio_toggle | digitalRead | gio_read | pinMode | gio_mode |
24 | |---------|--------------|-----------|------------|-------------|------------|--------------|------------|
25 | | AVR | 1.47 (0.68) | 0.06 (16) | 0.06 (16) | 3.23 (0.31) | 0.13 (8) | 3.33 (0.3) | 0.13 (8) |
26 | | ESP8266 | 1.56 (0.64) | 0.08 (12) | 0.5 (2) | 0.56 (1.8) | 0.21 (4.8) | 1.43 (0.7) | 0.67 (1.5) |
27 | | ESP32 | 0.33 (3) | 0.04 (24) | 0.13 (8) | 1.67 (0.6) | 0.08 (12) | 16.67 (0.06) | 0.08 (12) |
28 | | ESP32C3 | 0.92 (1) | 0.06 (16) | 0.19 (5.2) | 0.25 (4) | 0.04 (24) | 20 (0.05) | 0.04 (24) |
29 | */
--------------------------------------------------------------------------------
/src/gio/gio_arduino.h:
--------------------------------------------------------------------------------
1 | #pragma once
2 | #include
3 |
4 | #include "gio_defs.h"
5 |
6 | namespace gio {
7 |
8 | // mode
9 | _GIO_INLINE void mode(int P, int V) {
10 | pinMode(P, V);
11 | }
12 |
13 | // read
14 | _GIO_INLINE int read(int P) {
15 | return digitalRead(P);
16 | }
17 |
18 | // high
19 | _GIO_INLINE void high(int P) {
20 | digitalWrite(P, 1);
21 | }
22 |
23 | // low
24 | _GIO_INLINE void low(int P) {
25 | digitalWrite(P, 0);
26 | }
27 |
28 | // write
29 | _GIO_INLINE void write(int P, int V) {
30 | digitalWrite(P, V);
31 | }
32 |
33 | // toggle
34 | _GIO_INLINE void toggle(int P) {
35 | digitalWrite(P, !digitalRead(P));
36 | }
37 |
38 | // init
39 | _GIO_INLINE void init(int P, int V = INPUT) {
40 | mode(P, V);
41 | }
42 |
43 | }
--------------------------------------------------------------------------------
/src/gio/gio_avr.h:
--------------------------------------------------------------------------------
1 | /*
2 | Optimized digital functions for AVR microcontrollers
3 | by Watterott electronic (www.watterott.com)
4 | based on https://code.google.com/p/digitalwritefast
5 | based on https://github.com/Arduino-IRremote/Arduino-IRremote/blob/master/src/digitalWriteFast.h
6 |
7 | License: BSD 3-Clause License (https://opensource.org/licenses/BSD-3-Clause)
8 | */
9 |
10 | #pragma once
11 | #if defined(__AVR__) || defined(ARDUINO_ARCH_AVR)
12 |
13 | #include
14 |
15 | #include "gio_defs.h"
16 |
17 | // =====================================================================
18 | // ============================== PINOUT ===============================
19 | // =====================================================================
20 |
21 | // --- Arduino Mega and ATmega128x/256x based boards ---
22 | #if (defined(ARDUINO_AVR_MEGA) || \
23 | defined(ARDUINO_AVR_MEGA1280) || \
24 | defined(ARDUINO_AVR_MEGA2560) || \
25 | defined(__AVR_ATmega1280__) || \
26 | defined(__AVR_ATmega1281__) || \
27 | defined(__AVR_ATmega2560__) || \
28 | defined(__AVR_ATmega2561__))
29 |
30 | #define __avr_pin_to_port(P) \
31 | (((P) >= 22 && (P) <= 29) ? &PORTA : ((((P) >= 10 && (P) <= 13) || ((P) >= 50 && (P) <= 53)) ? &PORTB : (((P) >= 30 && (P) <= 37) ? &PORTC : ((((P) >= 18 && (P) <= 21) || (P) == 38) ? &PORTD : ((((P) <= 3) || (P) == 5) ? &PORTE : (((P) >= 54 && (P) <= 61) ? &PORTF : ((((P) >= 39 && (P) <= 41) || (P) == 4) ? &PORTG : ((((P) >= 6 && (P) <= 9) || (P) == 16 || (P) == 17) ? &PORTH : (((P) == 14 || (P) == 15) ? &PORTJ : (((P) >= 62 && (P) <= 69) ? &PORTK : &PORTL))))))))))
32 |
33 | #define __avr_pin_to_ddr(P) \
34 | (((P) >= 22 && (P) <= 29) ? &DDRA : ((((P) >= 10 && (P) <= 13) || ((P) >= 50 && (P) <= 53)) ? &DDRB : (((P) >= 30 && (P) <= 37) ? &DDRC : ((((P) >= 18 && (P) <= 21) || (P) == 38) ? &DDRD : ((((P) <= 3) || (P) == 5) ? &DDRE : (((P) >= 54 && (P) <= 61) ? &DDRF : ((((P) >= 39 && (P) <= 41) || (P) == 4) ? &DDRG : ((((P) >= 6 && (P) <= 9) || (P) == 16 || (P) == 17) ? &DDRH : (((P) == 14 || (P) == 15) ? &DDRJ : (((P) >= 62 && (P) <= 69) ? &DDRK : &DDRL))))))))))
35 |
36 | #define __avr_pin_to_pin(P) \
37 | (((P) >= 22 && (P) <= 29) ? &PINA : ((((P) >= 10 && (P) <= 13) || ((P) >= 50 && (P) <= 53)) ? &PINB : (((P) >= 30 && (P) <= 37) ? &PINC : ((((P) >= 18 && (P) <= 21) || (P) == 38) ? &PIND : ((((P) <= 3) || (P) == 5) ? &PINE : (((P) >= 54 && (P) <= 61) ? &PINF : ((((P) >= 39 && (P) <= 41) || (P) == 4) ? &PING : ((((P) >= 6 && (P) <= 9) || (P) == 16 || (P) == 17) ? &PINH : (((P) == 14 || (P) == 15) ? &PINJ : (((P) >= 62 && (P) <= 69) ? &PINK : &PINL))))))))))
38 |
39 | #define __avr_pin_to_bit(P) \
40 | (((P) >= 7 && (P) <= 9) ? (P)-3 : (((P) >= 10 && (P) <= 13) ? (P)-6 : (((P) >= 22 && (P) <= 29) ? (P)-22 : (((P) >= 30 && (P) <= 37) ? 37 - (P) : (((P) >= 39 && (P) <= 41) ? 41 - (P) : (((P) >= 42 && (P) <= 49) ? 49 - (P) : (((P) >= 50 && (P) <= 53) ? 53 - (P) : (((P) >= 54 && (P) <= 61) ? (P)-54 : (((P) >= 62 && (P) <= 69) ? (P)-62 : (((P) == 0 || (P) == 15 || (P) == 17 || (P) == 21) ? 0 : (((P) == 1 || (P) == 14 || (P) == 16 || (P) == 20) ? 1 : (((P) == 19) ? 2 : (((P) == 5 || (P) == 6 || (P) == 18) ? 3 : (((P) == 2) ? 4 : (((P) == 3 || (P) == 4) ? 5 : 7)))))))))))))))
41 |
42 | // --- Arduino MightyCore standard pinout ---
43 | #elif (defined(__AVR_ATmega1284P__) || \
44 | defined(__AVR_ATmega1284__) || \
45 | defined(__AVR_ATmega644P__) || \
46 | defined(__AVR_ATmega644A__) || \
47 | defined(__AVR_ATmega644__) || \
48 | defined(__AVR_ATmega324PB__) || \
49 | defined(__AVR_ATmega324PA__) || \
50 | defined(__AVR_ATmega324P__) || \
51 | defined(__AVR_ATmega324A__) || \
52 | defined(__AVR_ATmega164P__) || \
53 | defined(__AVR_ATmega164A__) || \
54 | defined(__AVR_ATmega32__) || \
55 | defined(__AVR_ATmega16__) || \
56 | defined(__AVR_ATmega8535__)) && \
57 | !defined(BOBUINO_PINOUT)
58 |
59 | #if defined(__AVR_ATmega324PB__)
60 | #define __avr_pin_to_port(P) \
61 | (((P) <= 7) ? &PORTB : (((P) >= 8 && (P) <= 15) ? &PORTD : (((P) >= 16 && (P) <= 23) ? &PORTC : (((P) >= 24 && (P) <= 31) ? &PORTA : &PORTE))))
62 | #define __avr_pin_to_ddr(P) \
63 | (((P) <= 7) ? &DDRB : (((P) >= 8 && (P) <= 15) ? &DDRD : (((P) >= 16 && (P) <= 23) ? &DDRC : (((P) >= 24 && (P) <= 31) ? &DDRA : &DDRE))))
64 | #define __avr_pin_to_pin(P) \
65 | (((P) <= 7) ? &PINB : (((P) >= 8 && (P) <= 15) ? &PIND : (((P) >= 16 && (P) <= 23) ? &PINC : (((P) >= 24 && (P) <= 31) ? &PINA : &PINE))))
66 | #define __avr_pin_to_bit(P) \
67 | (((P) <= 7) ? (P) : (((P) >= 8 && (P) <= 15) ? (P)-8 : (((P) >= 16 && (P) <= 23) ? (P)-16 : (((P) >= 16 && (P) <= 23) ? (P)-24 : (P)-32))))
68 | #elif defined(PORTA)
69 | #define __avr_pin_to_port(P) \
70 | (((P) <= 7) ? &PORTB : (((P) >= 8 && (P) <= 15) ? &PORTD : (((P) >= 16 && (P) <= 23) ? &PORTC : &PORTA)))
71 | #define __avr_pin_to_ddr(P) \
72 | (((P) <= 7) ? &DDRB : (((P) >= 8 && (P) <= 15) ? &DDRD : (((P) >= 16 && (P) <= 23) ? &DDRC : &DDRA)))
73 | #define __avr_pin_to_pin(P) \
74 | (((P) <= 7) ? &PINB : (((P) >= 8 && (P) <= 15) ? &PIND : (((P) >= 16 && (P) <= 23) ? &PINC : &PINA)))
75 | #define __avr_pin_to_bit(P) \
76 | (((P) <= 7) ? (P) : (((P) >= 8 && (P) <= 15) ? (P)-8 : (((P) >= 16 && (P) <= 23) ? (P)-16 : (P)-24)))
77 | #else
78 | #define __avr_pin_to_port(P) \
79 | (((P) <= 7) ? &PORTB : (((P) >= 8 && (P) <= 15) ? &PORTD : &PORTC))
80 | #define __avr_pin_to_ddr(P) \
81 | (((P) <= 7) ? &DDRB : (((P) >= 8 && (P) <= 15) ? &DDRD : &DDRC))
82 | #define __avr_pin_to_pin(P) \
83 | (((P) <= 7) ? &PINB : (((P) >= 8 && (P) <= 15) ? &PIND : &PINC))
84 | #define __avr_pin_to_bit(P) \
85 | (((P) <= 7) ? (P) : (((P) >= 8 && (P) <= 15) ? (P)-8 : (((P) >= 16 && (P) <= 23) ? (P)-16 : (P)-24)))
86 | #endif
87 |
88 | // --- Arduino Leonardo and ATmega16U4/32U4 based boards ---
89 | #elif (defined(ARDUINO_AVR_LEONARDO) || \
90 | defined(__AVR_ATmega16U4__) || \
91 | defined(__AVR_ATmega32U4__))
92 | #if defined(TEENSYDUINO)
93 |
94 | #define __avr_pin_to_port(P) \
95 | ((((P) <= 4) || ((P) >= 13 && (P) <= 15)) ? &PORTB : (((P) == 9 || (P) == 10) ? &PORTC : (((P) >= 16 && (P) <= 21)) ? &PORTF \
96 | : &PORTD))
97 | #define __avr_pin_to_ddr(P) \
98 | ((((P) <= 4) || ((P) >= 13 && (P) <= 15)) ? &DDRB : (((P) == 9 || (P) == 10) ? &DDRC : (((P) >= 16 && (P) <= 21)) ? &DDRF \
99 | : &DDRD))
100 | #define __avr_pin_to_pin(P) \
101 | ((((P) <= 4) || ((P) >= 13 && (P) <= 15)) ? &PINB : (((P) == 9 || (P) == 10) ? &PINC : (((P) >= 16 && (P) <= 21)) ? &PINF \
102 | : &PIND))
103 | #define __avr_pin_to_bit(P) \
104 | (((P) <= 3) ? (P) : (((P) == 4 || (P) == 12) ? 7 : (((P) <= 8) ? (P)-5 : (((P) <= 10) ? (P)-3 : (((P) == 11) ? 6 : (((P) <= 15) ? (P)-9 : (((P) <= 19) ? 23 - (P) : (((P) <= 21) ? 21 - (P) : (P)-18))))))))
105 | #else
106 |
107 | #define __avr_pin_to_port(P) \
108 | ((((P) <= 4) || (P) == 6 || (P) == 12 || (P) == 24 || (P) == 25 || (P) == 29) ? &PORTD : (((P) == 5 || (P) == 13) ? &PORTC : (((P) >= 18 && (P) <= 23)) ? &PORTF \
109 | : (((P) == 7) ? &PORTE : &PORTB)))
110 | #define __avr_pin_to_ddr(P) \
111 | ((((P) <= 4) || (P) == 6 || (P) == 12 || (P) == 24 || (P) == 25 || (P) == 29) ? &DDRD : (((P) == 5 || (P) == 13) ? &DDRC : (((P) >= 18 && (P) <= 23)) ? &DDRF \
112 | : (((P) == 7) ? &DDRE : &DDRB)))
113 | #define __avr_pin_to_pin(P) \
114 | ((((P) <= 4) || (P) == 6 || (P) == 12 || (P) == 24 || (P) == 25 || (P) == 29) ? &PIND : (((P) == 5 || (P) == 13) ? &PINC : (((P) >= 18 && (P) <= 23)) ? &PINF \
115 | : (((P) == 7) ? &PINE : &PINB)))
116 | #define __avr_pin_to_bit(P) \
117 | (((P) >= 8 && (P) <= 11) ? (P)-4 : (((P) >= 18 && (P) <= 21) ? 25 - (P) : (((P) == 0) ? 2 : (((P) == 1) ? 3 : (((P) == 2) ? 1 : (((P) == 3) ? 0 : (((P) == 4) ? 4 : (((P) == 6) ? 7 : (((P) == 13) ? 7 : (((P) == 14) ? 3 : (((P) == 15) ? 1 : (((P) == 16) ? 2 : (((P) == 17) ? 0 : (((P) == 22) ? 1 : (((P) == 23) ? 0 : (((P) == 24) ? 4 : (((P) == 25) ? 7 : (((P) == 26) ? 4 : (((P) == 27) ? 5 : 6)))))))))))))))))))
118 | #endif
119 |
120 | // --- Arduino Uno and ATmega168/328 based boards ---
121 | #elif (defined(ARDUINO_AVR_UNO) || \
122 | defined(ARDUINO_AVR_DUEMILANOVE) || \
123 | defined(__AVR_ATmega8__) || \
124 | defined(__AVR_ATmega48__) || \
125 | defined(__AVR_ATmega48P__) || \
126 | defined(__AVR_ATmega48PB__) || \
127 | defined(__AVR_ATmega88P__) || \
128 | defined(__AVR_ATmega88PB__) || \
129 | defined(__AVR_ATmega168__) || \
130 | defined(__AVR_ATmega168PA__) || \
131 | defined(__AVR_ATmega168PB__) || \
132 | defined(__AVR_ATmega328__) || \
133 | defined(__AVR_ATmega328P__) || \
134 | defined(__AVR_ATmega328PB__))
135 |
136 | #if defined(__AVR_ATmega48PB__) || defined(__AVR_ATmega88PB__) || defined(__AVR_ATmega168PB__) || defined(__AVR_ATmega328PB__)
137 | #define __avr_pin_to_port(P) \
138 | (((P) <= 7) ? &PORTD : (((P) >= 8 && (P) <= 13) ? &PORTB : (((P) >= 14 && (P) <= 19) ? &PORTC : &PORTE)))
139 | #define __avr_pin_to_ddr(P) \
140 | (((P) <= 7) ? &DDRD : (((P) >= 8 && (P) <= 13) ? &DDRB : (((P) >= 14 && (P) <= 19) ? &DDRC : &DDRE)))
141 | #define __avr_pin_to_pin(P) \
142 | (((P) <= 7) ? &PIND : (((P) >= 8 && (P) <= 13) ? &PINB : (((P) >= 14 && (P) <= 19) ? &PINC : &PINE)))
143 | #define __avr_pin_to_bit(P) \
144 | (((P) <= 7) ? (P) : (((P) >= 8 && (P) <= 13) ? (P)-8 : (((P) >= 14 && (P) <= 19) ? (P)-14 : (((P) >= 20 && (P) <= 21) ? (P)-18 : (P)-22))))
145 | #else
146 | #define __avr_pin_to_port(P) \
147 | (((P) <= 7) ? &PORTD : (((P) >= 8 && (P) <= 13) ? &PORTB : &PORTC))
148 | #define __avr_pin_to_ddr(P) \
149 | (((P) <= 7) ? &DDRD : (((P) >= 8 && (P) <= 13) ? &DDRB : &DDRC))
150 | #define __avr_pin_to_pin(P) \
151 | (((P) <= 7) ? &PIND : (((P) >= 8 && (P) <= 13) ? &PINB : &PINC))
152 | #define __avr_pin_to_bit(P) \
153 | (((P) <= 7) ? (P) : (((P) >= 8 && (P) <= 13) ? (P)-8 : (P)-14))
154 | #endif
155 |
156 | // --- Arduino Uno WiFi Rev 2, Nano Every ---
157 | #elif defined(__AVR_ATmega4809__)
158 |
159 | #define __avr_pin_to_port(P) \
160 | (((P) == 2 || (P) == 7) ? &VPORTA.OUT : ((P) == 5 || (P) == 9 || (P) == 10) ? &VPORTB.OUT \
161 | : ((P) == 4) ? &VPORTC.OUT \
162 | : (((P) >= 14 && (P) <= 17) || (P) == 20 || (P) == 21) ? &VPORTD.OUT \
163 | : ((P) == 8 || (P) == 11 || (P) == 12 || (P) == 13) ? &VPORTE.OUT \
164 | : &VPORTF.OUT)
165 | #define __avr_pin_to_ddr(P) \
166 | (((P) == 2 || (P) == 7) ? &VPORTA.DIR : ((P) == 5 || (P) == 9 || (P) == 10) ? &VPORTB.DIR \
167 | : ((P) == 4) ? &VPORTC.DIR \
168 | : (((P) >= 14 && (P) <= 17) || (P) == 20 || (P) == 21) ? &VPORTD.DIR \
169 | : ((P) == 8 || (P) == 11 || (P) == 12 || (P) == 13) ? &VPORTE.DIR \
170 | : &VPORTF.DIR)
171 | #define __avr_pin_to_pin(P) \
172 | (((P) == 2 || (P) == 7) ? &VPORTA.IN : ((P) == 5 || (P) == 9 || (P) == 10) ? &VPORTB.IN \
173 | : ((P) == 4) ? &VPORTC.IN \
174 | : (((P) >= 14 && (P) <= 17) || (P) == 20 || (P) == 21) ? &VPORTD.IN \
175 | : ((P) == 8 || (P) == 11 || (P) == 12 || (P) == 13) ? &VPORTE.IN \
176 | : &VPORTF.IN)
177 | #define __avr_pin_to_bit(P) \
178 | (((P) == 2 || (P) == 9 || (P) == 11 || (P) == 17) ? 0 : ((P) == 7 || (P) == 10 || (P) == 12 || (P) == 16) ? 1 \
179 | : ((P) == 5 || (P) == 13 || (P) == 15 || (P) == 18) ? 2 \
180 | : ((P) == 9 || (P) == 14 || (P) == 19) ? 3 \
181 | : ((P) == 6 || (P) == 20) ? 4 \
182 | : ((P) == 3 || (P) == 21) ? 5 \
183 | : 6)
184 |
185 | // TinyCore
186 | // https://raw.githubusercontent.com/xukangmin/TinyCore/master/avr/package/package_tinycore_index.json
187 | // https://docs.tinycore.dev/en/latest/
188 | #elif defined(__AVR_ATtiny1616__) || defined(__AVR_ATtiny3216__) || defined(__AVR_ATtiny3217__)
189 | #define __avr_pin_to_port(P) ((P) <= 5 ? &VPORTB.OUT : ((P) <= 9 ? &VPORTC.OUT : ((P) <= 16 ? &VPORTA.OUT : ((P) <= 18 ? &VPORTB.OUT : &VPORTC.OUT))))
190 | #define __avr_pin_to_ddr(P) ((P) <= 5 ? &VPORTB.DIR : ((P) <= 9 ? &VPORTC.DIR : ((P) <= 16 ? &VPORTA.DIR : ((P) <= 18 ? &VPORTB.DIR : &VPORTC.DIR))))
191 | #define __avr_pin_to_pin(P) ((P) <= 5 ? &VPORTB.IN : ((P) <= 9 ? &VPORTC.IN : ((P) <= 16 ? &VPORTA.IN : ((P) <= 18 ? &VPORTB.IN : &VPORTC.IN))))
192 | #define __avr_pin_to_bit(P) ((P) <= 3 ? (3 - P) : ((P) <= 5 ? (P) : ((P) <= 9 ? (P - 6) : ((P) <= 16 ? ((P)-9) : ((P) <= 18 ? ((P)-11) : ((P)-15))))))
193 |
194 | #elif defined(__AVR_ATtiny1614__)
195 | #define __avr_pin_to_port(P) ((P) <= 3 ? &VPORTA.OUT : ((P) <= 7 ? &VPORTB.OUT : &VPORTA.OUT))
196 | #define __avr_pin_to_ddr(P) ((P) <= 3 ? &VPORTA.DIR : ((P) <= 7 ? &VPORTB.DIR : &VPORTA.DIR))
197 | #define __avr_pin_to_pin(P) ((P) <= 3 ? &VPORTA.IN : ((P) <= 7 ? &VPORTB.IN : &VPORTA.IN))
198 | #define __avr_pin_to_bit(P) ((P) <= 3 ? (P + 4) : ((P) <= 7 ? (7 - P) : ((P) <= 10 ? (P - 7) : (P)-11)))
199 |
200 | #elif defined(__AVR_ATtiny816__)
201 | // https://github.com/Arduino-IRremote/Arduino-IRremote/discussions/1029
202 | #define __avr_pin_to_port(P) ((P) <= 3 ? &VPORTA.OUT : ((P) <= 9 ? &VPORTB.OUT : ((P) <= 13 ? &VPORTC.OUT : ((P) <= 17 ? &VPORTA.OUT : &VPORTC.OUT))))
203 | #define __avr_pin_to_ddr(P) ((P) <= 3 ? &VPORTA.DIR : ((P) <= 9 ? &VPORTB.DIR : ((P) <= 13 ? &VPORTC.DIR : ((P) <= 17 ? &VPORTA.DIR : &VPORTC.DIR))))
204 | #define __avr_pin_to_pin(P) ((P) <= 3 ? &VPORTA.IN : ((P) <= 9 ? &VPORTB.IN : ((P) <= 13 ? &VPORTC.IN : ((P) <= 17 ? &VPORTA.IN : &VPORTC.IN))))
205 | #define __avr_pin_to_bit(P) ((P) <= 3 ? (P + 4) : ((P) <= 9 ? (9 - P) : ((P) <= 13 ? (P - 10) : ((P) <= 16 ? (P - 13) : ((P)-17)))))
206 |
207 | // --- ATtinyX5 ---
208 | #elif defined(__AVR_ATtiny25__) || defined(__AVR_ATtiny45__) || defined(__AVR_ATtiny85__)
209 | // we have only PORTB
210 | #define __avr_pin_to_port(P) (&PORTB)
211 | #define __avr_pin_to_ddr(P) (&DDRB)
212 | #define __avr_pin_to_pin(P) (&PINB)
213 | #define __avr_pin_to_bit(P) (((P) <= 7) ? (P) : (((P) >= 8 && (P) <= 13) ? (P)-8 : (P)-14))
214 |
215 | // --- ATtiny88 ---
216 | #elif defined(__AVR_ATtiny88__)
217 | #if defined(ARDUINO_AVR_DIGISPARKPRO)
218 | #define __avr_pin_to_port(P) ((P) <= 7 ? &PORTD : ((P) <= 14 ? &PORTB : ((P) <= 18 ? &PORTA : &PORTC)))
219 | #define __avr_pin_to_ddr(P) ((P) <= 7 ? &DDRD : ((P) <= 14 ? &DDRB : ((P) <= 18 ? &DDRA : &DDRC)))
220 | #define __avr_pin_to_pin(P) ((P) <= 7 ? &PIND : ((P) <= 14 ? &PINB : ((P) <= 18 ? &PINA : &PINC)))
221 | #define __avr_pin_to_bit(P) ((P) <= 7 ? (P) : ((P) <= 13 ? ((P)-8) : ((P) == 14 ? 7 : ((P) <= 16 ? ((P)-14) : ((P) <= 18 ? ((P)-17) : ((P) == 25 ? 7 : ((P)-19)))))))
222 | #else
223 | #define __avr_pin_to_port(P) ((P) <= 7 ? &PORTD : ((P) <= 15 ? &PORTB : ((P) <= 22 ? &PORTC : ((P) <= 26 ? &PORTA : &PORTC))))
224 | #define __avr_pin_to_ddr(P) ((P) <= 7 ? &DDRD : ((P) <= 15 ? &DDRB : ((P) <= 22 ? &DDRC : ((P) <= 26 ? &DDRA : &DDRC))))
225 | #define __avr_pin_to_pin(P) ((P) <= 7 ? &PIND : ((P) <= 15 ? &PINB : ((P) <= 22 ? &PINC : ((P) <= 26 ? &PINA : &PINC))))
226 | #define __avr_pin_to_bit(P) ((P) <= 15 ? ((P)&0x7) : ((P) == 16 ? (7) : ((P) <= 22 ? ((P)-17) : ((P) == 27 ? (6) : ((P)-23)))))
227 | #endif
228 |
229 | // --- ATtinyX4 + ATtinyX7 ---
230 | #elif defined(__AVR_ATtiny24__) || defined(__AVR_ATtiny44__) || defined(__AVR_ATtiny84__) || defined(__AVR_ATtiny441__) || defined(__AVR_ATtiny841__) || defined(__AVR_ATtiny87__) || defined(__AVR_ATtiny167__)
231 | #if defined(ARDUINO_AVR_DIGISPARKPRO) || PIN_PA7 == 5
232 | // Strange enumeration of pins on Digispark board and core library
233 | #define __avr_pin_to_port(P) (((P) <= 4) ? &PORTB : &PORTA)
234 | #define __avr_pin_to_ddr(P) (((P) <= 4) ? &DDRB : &DDRA)
235 | #define __avr_pin_to_pin(P) (((P) <= 4) ? &PINB : &PINA)
236 | #define __avr_pin_to_bit(P) (((P) <= 2) ? (P) : (((P) == 3) ? 6 : (((P) == 4) ? 3 : (((P) == 5) ? 7 : (P)-6))))
237 | #else
238 | // ATtinyX4: PORTA for 0 to 7, PORTB for 8 to 11
239 | // ATtinyX7: PORTA for 0 to 7, PORTB for 8 to 15
240 | #define __avr_pin_to_port(P) (((P) <= 7) ? &PORTA : &PORTB)
241 | #define __avr_pin_to_ddr(P) (((P) <= 7) ? &DDRA : &DDRB)
242 | #define __avr_pin_to_pin(P) (((P) <= 7) ? &PINA : &PINB)
243 | #endif
244 | #if defined(__AVR_ATtiny24__) || defined(__AVR_ATtiny44__) || defined(__AVR_ATtiny84__) || defined(__AVR_ATtiny441__) || defined(__AVR_ATtiny841__)
245 | // https://github.com/SpenceKonde/ATTinyCore/blob/v2.0.0-devThis-is-the-head-submit-PRs-against-this/avr/variants/tinyx41_cw/pins_arduino.h#L334
246 | // Clockwise layout
247 | #define __avr_pin_to_bit(P) (((P) <= 7) ? (P) : ((P) == 11 ? (3) : 10 - (P)))
248 | #else
249 | #define __avr_pin_to_bit(P) (((P) <= 7) ? (P) : (P)-8)
250 | #endif
251 |
252 | #endif
253 |
254 | // =====================================================================
255 | // ============================== IO FUNC ==============================
256 | // =====================================================================
257 |
258 | namespace gio {
259 |
260 | // mode
261 | _GIO_INLINE void mode(int P, int V) {
262 | #if defined(__avr_pin_to_port)
263 | if (__builtin_constant_p(P) && __builtin_constant_p(V)) {
264 | switch (V) {
265 | case INPUT:
266 | bitClear(*__avr_pin_to_ddr(P), __avr_pin_to_bit(P));
267 | bitClear(*__avr_pin_to_port(P), __avr_pin_to_bit(P));
268 | break;
269 | case INPUT_PULLUP:
270 | bitClear(*__avr_pin_to_ddr(P), __avr_pin_to_bit(P));
271 | bitSet(*__avr_pin_to_port(P), __avr_pin_to_bit(P));
272 | break;
273 | case OUTPUT:
274 | bitSet(*__avr_pin_to_ddr(P), __avr_pin_to_bit(P));
275 | break;
276 | }
277 | } else
278 | #endif
279 | {
280 | switch (V) {
281 | case INPUT:
282 | greg_clr(portModeRegister(digitalPinToPort(P)), digitalPinToBitMask(P));
283 | greg_clr(portOutputRegister(digitalPinToPort(P)), digitalPinToBitMask(P));
284 | break;
285 | case INPUT_PULLUP:
286 | greg_clr(portModeRegister(digitalPinToPort(P)), digitalPinToBitMask(P));
287 | greg_set(portOutputRegister(digitalPinToPort(P)), digitalPinToBitMask(P));
288 | break;
289 | case OUTPUT:
290 | greg_set(portModeRegister(digitalPinToPort(P)), digitalPinToBitMask(P));
291 | break;
292 | }
293 | }
294 | }
295 |
296 | // read
297 | _GIO_INLINE int read(int P) {
298 | #if defined(__avr_pin_to_pin)
299 | if (__builtin_constant_p(P)) {
300 | return (bitRead(*__avr_pin_to_pin(P), __avr_pin_to_bit(P))) ? 1 : 0;
301 | } else
302 | #endif
303 | {
304 | return greg_read(portInputRegister(digitalPinToPort(P)), digitalPinToBitMask(P));
305 | }
306 | }
307 |
308 | // high
309 | _GIO_INLINE void high(int P) {
310 | #if defined(__avr_pin_to_port)
311 | if (__builtin_constant_p(P)) {
312 | bitSet(*__avr_pin_to_port(P), __avr_pin_to_bit(P));
313 | } else
314 | #endif
315 | {
316 | greg_set(portOutputRegister(digitalPinToPort(P)), digitalPinToBitMask(P));
317 | }
318 | }
319 |
320 | // low
321 | _GIO_INLINE void low(int P) {
322 | #if defined(__avr_pin_to_port)
323 | if (__builtin_constant_p(P)) {
324 | bitClear(*__avr_pin_to_port(P), __avr_pin_to_bit(P));
325 | } else
326 | #endif
327 | {
328 | greg_clr(portOutputRegister(digitalPinToPort(P)), digitalPinToBitMask(P));
329 | }
330 | }
331 |
332 | // write
333 | _GIO_INLINE void write(int P, int V) {
334 | V ? high(P) : low(P);
335 | }
336 |
337 | // toggle
338 | _GIO_INLINE void toggle(int P) {
339 | #if defined(__avr_pin_to_pin)
340 | if (__builtin_constant_p(P)) {
341 | bitSet(*__avr_pin_to_pin(P), __avr_pin_to_bit(P));
342 | } else
343 | #endif
344 | {
345 | greg_set(portInputRegister(digitalPinToPort(P)), digitalPinToBitMask(P));
346 | }
347 | }
348 |
349 | // init
350 | _GIO_INLINE void init(int P, int V = INPUT) {
351 | mode(P, V);
352 | }
353 |
354 | } // namespace gio
355 |
356 | #endif
--------------------------------------------------------------------------------
/src/gio/gio_defs.h:
--------------------------------------------------------------------------------
1 | #pragma once
2 |
3 | #define _GIO_INLINE static inline __attribute__((always_inline))
4 | #define greg_set(reg, mask) *reg |= mask
5 | #define greg_clr(reg, mask) *reg &= ~mask
6 | #define greg_write(reg, mask, val) (val) ? greg_set(reg, mask) : greg_clr(reg, mask)
7 | #define greg_read(reg, mask) (bool)(*reg & mask)
--------------------------------------------------------------------------------
/src/gio/gio_esp32.h:
--------------------------------------------------------------------------------
1 | // based on https://github.com/PaulStoffregen/OneWire/blob/master/util/OneWire_direct_gpio.h
2 |
3 | #pragma once
4 | #if defined(ESP32) || defined(ARDUINO_ARCH_ESP32)
5 |
6 | #include
7 | #include
8 | #include
9 |
10 | #include "gio_defs.h"
11 |
12 | #if ESP_IDF_VERSION_MAJOR < 4
13 | #define _ESP32_IDF_V3_REG() \
14 | uint32_t rtc_reg(rtc_gpio_desc[pin].reg); \
15 | if (rtc_reg) { \
16 | ESP_REG(rtc_reg) = ESP_REG(rtc_reg) & ~(rtc_gpio_desc[pin].mux); \
17 | ESP_REG(rtc_reg) = ESP_REG(rtc_reg) & ~(rtc_gpio_desc[pin].pullup | rtc_gpio_desc[pin].pulldown); \
18 | }
19 | #else
20 | #define _ESP32_IDF_V3_REG()
21 | #endif
22 |
23 | #define _IS_ESP_Cx_ defined(CONFIG_IDF_TARGET_ESP32C3) || defined(CONFIG_IDF_TARGET_ESP32C6)
24 |
25 | namespace gio {
26 |
27 | // mode
28 | _GIO_INLINE void mode(uint8_t pin, uint8_t mode) {
29 | switch (mode) {
30 | case INPUT:
31 | #if _IS_ESP_Cx_
32 | GPIO.enable_w1tc.val = (1ul << (pin));
33 | #else
34 | if (digitalPinIsValid(pin)) {
35 | _ESP32_IDF_V3_REG();
36 | if (pin < 32) GPIO.enable_w1tc = (1ul << pin);
37 | else GPIO.enable1_w1tc.val = (1ul << (pin - 32));
38 | }
39 | #endif
40 | break;
41 |
42 | case OUTPUT:
43 | #if _IS_ESP_Cx_
44 | GPIO.enable_w1ts.val = (1ul << (pin));
45 | #else
46 | if (digitalPinIsValid(pin)) {
47 | _ESP32_IDF_V3_REG();
48 | if (pin < 32) GPIO.enable_w1ts = (1ul << pin);
49 | else GPIO.enable1_w1ts.val = (1ul << (pin - 32));
50 | }
51 | #endif
52 | break;
53 |
54 | default:
55 | pinMode(pin, mode);
56 | break;
57 | }
58 | }
59 |
60 | // read
61 | _GIO_INLINE int read(uint8_t pin) {
62 | #if _IS_ESP_Cx_
63 | return (GPIO.in.val >> pin) & 0x1;
64 | #else
65 | if (digitalPinIsValid(pin)) {
66 | if (pin < 32) return (GPIO.in >> pin) & 0x1;
67 | else return (GPIO.in1.val >> (pin - 32)) & 0x1;
68 | }
69 | #endif
70 | return 0;
71 | }
72 |
73 | // low
74 | _GIO_INLINE void low(uint8_t pin) {
75 | #if _IS_ESP_Cx_
76 | GPIO.out_w1tc.val = (1ul << pin);
77 | #else
78 | if (digitalPinIsValid(pin)) {
79 | if (pin < 32) GPIO.out_w1tc = (1ul << pin);
80 | else GPIO.out1_w1tc.val = (1ul << (pin - 32));
81 | }
82 | #endif
83 | }
84 |
85 | // high
86 | _GIO_INLINE void high(uint8_t pin) {
87 | #if _IS_ESP_Cx_
88 | GPIO.out_w1ts.val = (1ul << pin);
89 | #else
90 | if (digitalPinIsValid(pin)) {
91 | if (pin < 32) GPIO.out_w1ts = (1ul << pin);
92 | else GPIO.out1_w1ts.val = (1ul << (pin - 32));
93 | }
94 | #endif
95 | }
96 |
97 | // write
98 | _GIO_INLINE void write(uint8_t pin, uint8_t val) {
99 | val ? high(pin) : low(pin);
100 | }
101 |
102 | // toggle
103 | _GIO_INLINE void toggle(uint8_t pin) {
104 | write(pin, !read(pin));
105 | }
106 |
107 | // init
108 | _GIO_INLINE void init(int P, int V = INPUT) {
109 | pinMode(P, V);
110 | }
111 |
112 | } // namespace gio
113 |
114 | #endif
--------------------------------------------------------------------------------
/src/gio/gio_esp8266.h:
--------------------------------------------------------------------------------
1 | #pragma once
2 | #if defined(ESP8266) || defined(ARDUINO_ARCH_ESP8266)
3 |
4 | #include
5 |
6 | #include "gio_defs.h"
7 |
8 | namespace gio {
9 |
10 | // mode
11 | _GIO_INLINE void mode(uint8_t pin, uint8_t mode) {
12 | // dsnt work
13 | // if (mode == INPUT) GPE &= ~(1 << pin);
14 | // else if (mode == OUTPUT) GPE |= (1 << pin);
15 |
16 | switch (mode) {
17 | case INPUT:
18 | case INPUT_PULLUP:
19 | if (pin < 16) {
20 | GPF(pin) = GPFFS(GPFFS_GPIO(pin));
21 | GPEC = (1 << pin);
22 | GPC(pin) = (GPC(pin) & (0xF << GPCI)) | (1 << GPCD);
23 | if (mode == INPUT_PULLUP) GPF(pin) |= (1 << GPFPU);
24 | } else if (pin == 16) {
25 | GPF16 = GP16FFS(GPFFS_GPIO(pin));
26 | GPC16 = 0;
27 | GP16E &= ~1;
28 | }
29 | break;
30 |
31 | case OUTPUT:
32 | if (pin < 16) {
33 | GPF(pin) = GPFFS(GPFFS_GPIO(pin));
34 | GPC(pin) = (GPC(pin) & (0xF << GPCI));
35 | GPES = (1 << pin);
36 | } else if (pin == 16) {
37 | GPF16 = GP16FFS(GPFFS_GPIO(pin));
38 | GPC16 = 0;
39 | GP16E |= 1;
40 | }
41 | break;
42 |
43 | default:
44 | pinMode(pin, mode);
45 | break;
46 | }
47 | }
48 |
49 | // read
50 | _GIO_INLINE int read(uint8_t pin) {
51 | return (pin < 16) ? GPIP(pin) : (GP16I & 0x01);
52 | }
53 |
54 | // low
55 | _GIO_INLINE void low(uint8_t pin) {
56 | if (pin < 16) GPOC = (1 << pin);
57 | else if (pin == 16) GP16O &= ~1;
58 | }
59 |
60 | // high
61 | _GIO_INLINE void high(uint8_t pin) {
62 | if (pin < 16) GPOS = (1 << pin);
63 | else if (pin == 16) GP16O |= 1;
64 | }
65 |
66 | // write
67 | _GIO_INLINE void write(uint8_t pin, uint8_t val) {
68 | val ? high(pin) : low(pin);
69 | }
70 |
71 | // toggle
72 | _GIO_INLINE void toggle(uint8_t pin) {
73 | if (pin < 16) {
74 | if (GPIP(pin)) GPOC = (1 << pin);
75 | else GPOS = (1 << pin);
76 | } else if (pin == 16) {
77 | if (GP16I & 0x01) GP16O &= ~1;
78 | else GP16O |= 1;
79 | }
80 | }
81 |
82 | // init
83 | _GIO_INLINE void init(int P, int V = INPUT) {
84 | mode(P, V);
85 | }
86 |
87 | } // namespace gio
88 |
89 | #endif
--------------------------------------------------------------------------------
/src/utils/PinIO.h:
--------------------------------------------------------------------------------
1 | #pragma once
2 |
3 | #include
4 |
5 | #include "../gio/gio.h"
6 |
7 | // #define GIO_NO_MASK
8 |
9 | namespace gio {
10 |
11 | // single mode pin (output/input)
12 | class PinIO {
13 | public:
14 | PinIO() {}
15 | PinIO(uint8_t npin, uint8_t mode = INPUT) {
16 | init(npin, mode);
17 | }
18 |
19 | void init(uint8_t npin, uint8_t mode = INPUT) {
20 | gio::init(npin, mode);
21 | #if defined(__AVR__) && !defined(GIO_NO_MASK)
22 | if (mode == OUTPUT) reg = portOutputRegister(digitalPinToPort(npin));
23 | else reg = portInputRegister(digitalPinToPort(npin));
24 | mask = digitalPinToBitMask(npin);
25 | #else
26 | pin = npin;
27 | #endif
28 | }
29 |
30 | void write(uint8_t val) {
31 | #if defined(__AVR__) && !defined(GIO_NO_MASK)
32 | greg_write(reg, mask, val);
33 | #else
34 | gio::write(pin, val);
35 | #endif
36 | }
37 |
38 | void high() {
39 | #if defined(__AVR__) && !defined(GIO_NO_MASK)
40 | greg_set(reg, mask);
41 | #else
42 | gio::high(pin);
43 | #endif
44 | }
45 |
46 | void low() {
47 | #if defined(__AVR__) && !defined(GIO_NO_MASK)
48 | greg_clr(reg, mask);
49 | #else
50 | gio::low(pin);
51 | #endif
52 | }
53 |
54 | void toggle() {
55 | #if defined(__AVR__) && !defined(GIO_NO_MASK)
56 | *reg ^= mask;
57 | #else
58 | gio::toggle(pin);
59 | #endif
60 | }
61 |
62 | int read() {
63 | #if defined(__AVR__) && !defined(GIO_NO_MASK)
64 | return greg_read(reg, mask);
65 | #else
66 | return gio::read(pin);
67 | #endif
68 | }
69 |
70 | private:
71 | #if defined(__AVR__) && !defined(GIO_NO_MASK)
72 | volatile uint8_t *reg;
73 | uint8_t mask = 0xff;
74 | #else
75 | uint8_t pin;
76 | #endif
77 | };
78 |
79 | } // namespace gio
--------------------------------------------------------------------------------
/src/utils/PinT.h:
--------------------------------------------------------------------------------
1 | #pragma once
2 |
3 | #include
4 |
5 | #include "../gio/gio.h"
6 | #include "../gio/gio_defs.h"
7 |
8 | namespace gio {
9 |
10 | template
11 | class PinT {
12 | public:
13 | PinT(uint8_t mode = INPUT) {
14 | gio::init(pin, mode);
15 | }
16 | _GIO_INLINE void mode(uint8_t mode) {
17 | gio::mode(pin, mode);
18 | }
19 | _GIO_INLINE void write(uint8_t val) {
20 | gio::write(pin, val);
21 | }
22 | _GIO_INLINE void high() {
23 | gio::high(pin);
24 | }
25 | _GIO_INLINE void low() {
26 | gio::low(pin);
27 | }
28 | _GIO_INLINE void toggle() {
29 | gio::toggle(pin);
30 | }
31 | _GIO_INLINE int read() {
32 | return gio::read(pin);
33 | }
34 | };
35 |
36 | } // namespace gio
--------------------------------------------------------------------------------
/src/utils/shift.cpp:
--------------------------------------------------------------------------------
1 | #include "shift.h"
2 |
3 | namespace gio {
4 | namespace shift {
5 |
6 | bool read(uint8_t dat_pin, uint8_t clk_pin, uint8_t order, uint8_t* data, uint16_t len, uint8_t delay) {
7 | bool dif = 0;
8 | if (order & 0b10) data += len - 1;
9 |
10 | #if defined(__AVR__) && !defined(GIO_NO_MASK)
11 | if (!__builtin_constant_p(dat_pin) || !__builtin_constant_p(clk_pin)) {
12 | volatile uint8_t* c_reg = portOutputRegister(digitalPinToPort(clk_pin));
13 | volatile uint8_t* d_reg = portInputRegister(digitalPinToPort(dat_pin));
14 | uint8_t c_mask = digitalPinToBitMask(clk_pin);
15 | uint8_t d_mask = digitalPinToBitMask(dat_pin);
16 | uint8_t val = 0;
17 | while (len--) {
18 | val = 0;
19 | for (uint8_t i = 0; i < 8; i++) {
20 | if (order & 0b01) { // MSBFIRST
21 | val <<= 1;
22 | if (greg_read(d_reg, d_mask)) val |= 1;
23 | } else {
24 | val >>= 1;
25 | if (greg_read(d_reg, d_mask)) val |= (1 << 7);
26 | }
27 | if (delay) delayMicroseconds(delay);
28 | greg_set(c_reg, c_mask);
29 | if (delay) delayMicroseconds(delay);
30 | greg_clr(c_reg, c_mask);
31 | }
32 | if (!dif && *data != val) dif = 1;
33 | *data = val;
34 | data += (order & 0b10) ? -1 : 1;
35 | }
36 | } else
37 | #endif
38 | {
39 | uint8_t val = 0;
40 | while (len--) {
41 | val = 0;
42 | for (uint8_t i = 0; i < 8; i++) {
43 | if (order & 0b01) { // MSBFIRST
44 | val <<= 1;
45 | if (gio::read(dat_pin)) val |= 1;
46 | } else {
47 | val >>= 1;
48 | if (gio::read(dat_pin)) val |= (1 << 7);
49 | }
50 | if (delay) delayMicroseconds(delay);
51 | gio::high(clk_pin);
52 | if (delay) delayMicroseconds(delay);
53 | gio::low(clk_pin);
54 | }
55 | if (!dif && *data != val) dif = 1;
56 | *data = val;
57 | data += (order & 0b10) ? -1 : 1;
58 | }
59 | }
60 | return dif;
61 | }
62 |
63 | uint8_t read_byte(uint8_t dat_pin, uint8_t clk_pin, uint8_t order, uint8_t delay) {
64 | uint8_t value;
65 | read(dat_pin, clk_pin, order, &value, 1, delay);
66 | return value;
67 | }
68 |
69 | bool read_cs(uint8_t dat_pin, uint8_t clk_pin, uint8_t cs_pin, uint8_t order, uint8_t* data, uint16_t len, uint8_t delay) {
70 | gio::low(cs_pin);
71 | bool res = read(dat_pin, clk_pin, order, data, len, delay);
72 | gio::high(cs_pin);
73 | return res;
74 | }
75 |
76 | uint8_t read_cs_byte(uint8_t dat_pin, uint8_t clk_pin, uint8_t cs_pin, uint8_t order, uint8_t delay) {
77 | uint8_t value;
78 | read_cs(dat_pin, clk_pin, cs_pin, order, &value, 1, delay);
79 | return value;
80 | }
81 |
82 | void send(uint8_t dat_pin, uint8_t clk_pin, uint8_t order, uint8_t* data, uint16_t len, uint8_t delay) {
83 | #if defined(__AVR__) && !defined(GIO_NO_MASK)
84 | if (!__builtin_constant_p(dat_pin) || !__builtin_constant_p(clk_pin)) {
85 | volatile uint8_t* c_reg = portOutputRegister(digitalPinToPort(clk_pin));
86 | volatile uint8_t* d_reg = portOutputRegister(digitalPinToPort(dat_pin));
87 | uint8_t c_mask = digitalPinToBitMask(clk_pin);
88 | uint8_t d_mask = digitalPinToBitMask(dat_pin);
89 | uint8_t val;
90 | for (uint16_t b = 0; b < len; b++) {
91 | val = data[(order & 0b10) ? (len - b - 1) : b];
92 | for (uint8_t i = 0; i < 8; i++) {
93 | if (order & 0b01) { // MSBFIRST
94 | greg_write(d_reg, d_mask, val & (1 << 7));
95 | val <<= 1;
96 | } else {
97 | greg_write(d_reg, d_mask, val & 1);
98 | val >>= 1;
99 | }
100 | if (delay) delayMicroseconds(delay);
101 | greg_set(c_reg, c_mask);
102 | if (delay) delayMicroseconds(delay);
103 | greg_clr(c_reg, c_mask);
104 | }
105 | }
106 | greg_clr(d_reg, d_mask);
107 | } else
108 | #endif
109 | {
110 | for (uint16_t b = 0; b < len; b++) {
111 | uint8_t val = data[(order & 0b10) ? (len - b - 1) : b];
112 | for (uint8_t i = 0; i < 8; i++) {
113 | if (order & 0b01) { // MSBFIRST
114 | gio::write(dat_pin, val & (1 << 7));
115 | val <<= 1;
116 | } else {
117 | gio::write(dat_pin, val & 1);
118 | val >>= 1;
119 | }
120 | if (delay) delayMicroseconds(delay);
121 | gio::high(clk_pin);
122 | if (delay) delayMicroseconds(delay);
123 | gio::low(clk_pin);
124 | }
125 | gio::low(dat_pin);
126 | }
127 | }
128 | }
129 |
130 | void send_byte(uint8_t dat_pin, uint8_t clk_pin, uint8_t order, uint8_t data, uint8_t delay) {
131 | send(dat_pin, clk_pin, order, &data, 1, delay);
132 | }
133 |
134 | void send_cs(uint8_t dat_pin, uint8_t clk_pin, uint8_t cs_pin, uint8_t order, uint8_t* data, uint16_t len, uint8_t delay) {
135 | gio::low(cs_pin);
136 | send(dat_pin, clk_pin, order, data, len, delay);
137 | gio::high(cs_pin);
138 | }
139 |
140 | void send_cs_byte(uint8_t dat_pin, uint8_t clk_pin, uint8_t cs_pin, uint8_t order, uint8_t data, uint8_t delay) {
141 | send_cs(dat_pin, clk_pin, cs_pin, order, &data, 1, delay);
142 | }
143 |
144 | } // namespace shift
145 | } // namespace gio
--------------------------------------------------------------------------------
/src/utils/shift.h:
--------------------------------------------------------------------------------
1 | #pragma once
2 |
3 | #include
4 |
5 | #include "../gio/gio.h"
6 |
7 | #define LSB_NORMAL 0b00
8 | #define MSB_NORMAL 0b01
9 | #define LSB_REVERSE 0b10
10 | #define MSB_REVERSE 0b11
11 |
12 | namespace gio {
13 | namespace shift {
14 |
15 | // read
16 | // прочитать пакет. Вернёт true, если хотя бы один бит отличается
17 | bool read(uint8_t dat_pin, uint8_t clk_pin, uint8_t order, uint8_t* data, uint16_t len, uint8_t delay = 0);
18 |
19 | // прочитать байт
20 | uint8_t read_byte(uint8_t dat_pin, uint8_t clk_pin, uint8_t order, uint8_t delay = 0);
21 |
22 | // прочитать пакет + cs пин. Вернёт true, если хотя бы один бит отличается
23 | bool read_cs(uint8_t dat_pin, uint8_t clk_pin, uint8_t cs_pin, uint8_t order, uint8_t* data, uint16_t len, uint8_t delay = 0);
24 |
25 | // прочитать байт + cs пин
26 | uint8_t read_cs_byte(uint8_t dat_pin, uint8_t clk_pin, uint8_t cs_pin, uint8_t order, uint8_t delay = 0);
27 |
28 | // send
29 | // отправить пакет
30 | void send(uint8_t dat_pin, uint8_t clk_pin, uint8_t order, uint8_t* data, uint16_t len, uint8_t delay = 0);
31 |
32 | // отправить байт
33 | void send_byte(uint8_t dat_pin, uint8_t clk_pin, uint8_t order, uint8_t data, uint8_t delay = 0);
34 |
35 | // отправить пакет + cs пин
36 | void send_cs(uint8_t dat_pin, uint8_t clk_pin, uint8_t cs_pin, uint8_t order, uint8_t* data, uint16_t len, uint8_t delay = 0);
37 |
38 | // отправить байт + cs пин
39 | void send_cs_byte(uint8_t dat_pin, uint8_t clk_pin, uint8_t cs_pin, uint8_t order, uint8_t data, uint8_t delay = 0);
40 |
41 | } // namespace shift
42 | } // namespace gio
43 |
44 | /*
45 | us byte (MHz)
46 | | | shiftOut | gio_send | gio_send (non-const) |
47 | |---------|--------------|----------|----------------------|
48 | | AVR | 100 (0.075) | 6 (1.3) | 11 (0.7) |
49 | */
--------------------------------------------------------------------------------