Compare commits

..

184 commits

Author SHA1 Message Date
Limor "Ladyada" Fried
e75ac29ca6
Merge pull request #145 from brentru/add-genericdevice-end
Add end() for GenericDevice
2025-06-28 19:34:03 -04:00
brentru
d8a04619f0 Add - end() for GenericDevice 2025-06-18 16:01:02 -04:00
Tyeth Gundry
a09a91d13e
Update library.properties - bump version to 1.17.1 2025-04-29 13:04:24 +01:00
Limor "Ladyada" Fried
159f86a3bd
Merge pull request #140 from mak0t0san/patch-1
Update CMakeLists.txt to include "Adafruit_GenericDevice.cpp"
2025-04-28 11:14:02 -04:00
Limor "Ladyada" Fried
5e8f137415
Merge pull request #144 from meshtastic/master
Add PORTDUINO check to Adafruit_SPIDevice.h
2025-04-28 11:13:42 -04:00
Jonathan Bennett
fcd9217179
fix for clang-format in Adafruit_SPIDevice.h 2025-04-26 09:47:42 -05:00
Jonathan Bennett
18a22e98ac
Add PORTDUINO check to Adafruit_SPIDevice.h
The PORTDUINO target on ARMv7 was triggering the defined(__arm__) code block, and failing compilation as a result. Quick fix to check for PORTDUINO.
2025-04-26 09:34:15 -05:00
Makoto Schoppert
276c7b3ad8
Update CMakeLists.txt
Missing source file "Adafruit_GenericDevice.cpp"
2025-01-31 22:43:45 -05:00
Limor "Ladyada" Fried
055013b58d
Merge pull request #139 from adafruit/genericdevice2
refactor the whole thing to get rid of static-ness. also clang examples
2025-01-08 15:13:46 -05:00
ladyada
186ea35211 reclang 2025-01-08 15:05:13 -05:00
ladyada
8a32dc72c9 refactor the whole thing to get rid of static-ness. also clang examples 2025-01-08 15:03:00 -05:00
Limor "Ladyada" Fried
cc66c422eb
Merge pull request #137 from adafruit/genericdevice
add generic device for non-standard transports
2025-01-08 10:38:11 -05:00
ladyada
1a7e578832 test skip for uart 2025-01-08 10:25:38 -05:00
ladyada
c6b5c0b2b7 Merge branch 'genericdevice' of github.com:adafruit/Adafruit_BusIO into genericdevice 2025-01-08 10:15:13 -05:00
ladyada
2663ca269f woops fix serial 2025-01-08 10:15:09 -05:00
Limor "Ladyada" Fried
ff26e5a112
Merge branch 'master' into genericdevice 2025-01-08 10:13:44 -05:00
Limor "Ladyada" Fried
55e4f835bc
Merge pull request #131 from johnboiles/master
For ESP-IDF builds use arduino-esp32 instead of arduino dependency
2025-01-08 09:39:59 -05:00
Limor "Ladyada" Fried
17506175b2
Merge pull request #136 from facchinm/improve_fast_pin_io
Avoid fast pins IO on RTOS based boards
2025-01-08 09:38:46 -05:00
ladyada
c0237922d3 add claude credits! 2025-01-08 09:35:51 -05:00
ladyada
fcc8dfaf63 bump 2025-01-08 09:31:54 -05:00
ladyada
70ad31700a some tests for uart mode 2025-01-08 09:30:58 -05:00
ladyada
c602ea03e0 doxyclanged! 2025-01-08 09:29:49 -05:00
ladyada
66448b37ec clang 2025-01-07 22:08:13 -05:00
ladyada
c43db9d7c2 still need to doxy/clang 2025-01-07 22:03:15 -05:00
Tyeth Gundry
9eda3f4641
Update library.properties - bump version to 1.16.3 2025-01-07 16:23:28 +00:00
ladyada
9bd286898c Merge branch 'master' of github.com:adafruit/Adafruit_BusIO 2025-01-05 15:12:18 -05:00
ladyada
14d379e4d3 small typo fix 2025-01-05 15:12:13 -05:00
Martino Facchin
c99c8564a2 fixup: clang-format fix 2024-12-16 09:41:55 +01:00
Martino Facchin
9eeac1d181 Avoid fast pins IO on RTOS based boards
Better fix than 80943e663f
2024-12-13 15:54:58 +01:00
Tyeth Gundry
ddf66b491e
Update library.properties - bump version to 1.16.2 2024-10-29 21:57:16 +00:00
Limor "Ladyada" Fried
0b68c51a4a
Merge pull request #135 from caternuson/giga_i2c_patch
Patch for GIGA I2C quirk
2024-10-24 17:46:15 -04:00
caternuson
31148fe857 clangerdified 2024-10-24 14:37:54 -07:00
caternuson
9af8ab9607 giga i2c hack fix 2024-10-24 14:25:57 -07:00
John Boiles
18df8eaf8b For ESP-IDF builds use arduino-esp32 instead of arduino dependency 2024-07-31 17:09:25 -07:00
Tyeth Gundry
15fbda592d
Update library.properties - bump version to 1.16.1 2024-05-21 12:15:23 +01:00
Ha Thach
fccf89cac9
Merge pull request #129 from silabs-bozont/master
Fix compatibility with Silicon Labs boards
2024-05-15 16:48:46 +07:00
Tamas Jozsi
95e8f81499 Fix compatibility with Silicon Labs boards
The Silicon Labs core moved to use ArduinoCore-API which
has a native 'BitOrder' definition
2024-05-10 17:48:14 +02:00
Tyeth Gundry
e1aa388418
Update library.properties - bump version to 1.16.0 2024-04-16 18:44:56 +01:00
Limor "Ladyada" Fried
970ccbfd67
Merge pull request #125 from mecparts/master
Add compatibility with Arduino R4 boards
2024-04-14 22:24:24 -04:00
mecparts
5f170d8e4f
Amended code formatting 2024-02-11 14:16:08 -07:00
mecparts
d5aa1a353e
Add compatibility with Arduino R4 boards 2024-02-11 13:28:45 -07:00
Tyeth Gundry
fc25cd4967
Update library.properties - bump version to 1.15.0 2024-01-16 19:08:05 +00:00
Ha Thach
ec19ba1d6c
Merge pull request #124 from silabs-bozont/master
Add compatibility with Silicon Labs Arduino boards
2024-01-11 11:42:02 +07:00
Tamas Jozsi
16e4726718 Add compatibility with Silicon Labs Arduino boards 2024-01-05 17:14:45 +01:00
Carter Nelson
9ebca64d82
Update library.properties 2023-10-10 09:30:15 -07:00
Limor "Ladyada" Fried
c07701e0b1
Merge pull request #121 from caternuson/esp32_warns
Remove volatile compound assignments
2023-10-09 18:09:30 -04:00
caternuson
2708c120c6 remove volatile compound assignments 2023-10-09 13:52:00 -07:00
ladyada
4d276155d7 klzng 2023-10-09 12:15:35 -04:00
ladyada
a9498c8f62 kick! 2023-10-09 12:13:50 -04:00
ladyada
ad776484f3 Merge branch 'master' of github.com:adafruit/Adafruit_BusIO 2023-09-25 00:53:11 -04:00
ladyada
fbba4799ad more specific debug during scan 2023-09-25 00:53:07 -04:00
Tyeth Gundry
ee0faec7ee
Update library.properties - bump version to 1.14.4 2023-09-19 11:39:09 +01:00
Dan Halbert
7cc1d0a5fd
Merge pull request #120 from Wol/patch-1
Remove offensive term in comments
2023-09-15 23:01:30 -04:00
Luke Lowrey
9108618560
Fix line length 2023-09-16 00:59:38 +01:00
Luke Lowrey
1b7f5a9590
Remove offensive term in comments
Tidying up the language used - https://dictionary.cambridge.org/dictionary/english/spaz https://en.wiktionary.org/wiki/spaz
2023-09-16 00:30:41 +01:00
Ha Thach
4f899a2dd6
Merge pull request #119 from OlafFilies/XMC_enable
By adding two macros all Infineons XMC MCUs are now able to use the l…
2023-09-13 13:46:01 +07:00
Filies Olaf (IFAG DES TOC PSA)
5162b240d7 Forgot the || inthe macro list 2023-09-11 17:21:18 +02:00
Filies Olaf (IFAG DES TOC PSA)
8097aa568f By adding two macros all Infineons XMC MCUs are now able to use the library 2023-09-11 16:50:03 +02:00
Tyeth Gundry
3ea940b745
Update library.properties - bump version to 1.14.3 2023-08-15 12:03:13 +01:00
Limor "Ladyada" Fried
5473c1801c
Merge pull request #117 from DeflateAwning/master
Add explicit type casting to fix build error
2023-08-13 13:53:57 -04:00
DeflateAwning
7fd30d0bf8 Add explicit type casting to fix build error 2023-06-21 23:25:44 -06:00
dherrada
42e31a252f Update CI action versions 2023-05-12 11:23:57 -04:00
Carter Nelson
186bfb005c
Update library.properties 2022-11-02 09:53:19 -07:00
Carter Nelson
6a2e9b6a88
Merge pull request #110 from caternuson/iss109
Init HW SPI members
2022-11-02 09:52:40 -07:00
caternuson
369413c66d init hw spi members 2022-11-01 12:23:15 -07:00
Eva Herrada
0348f74375
Bump to 1.14.0 2022-10-25 17:24:30 -04:00
Carter Nelson
8f3a45e263
Merge pull request #108 from caternuson/iss81_spi_refac
Refactor for better SW SPI only support
2022-10-24 10:58:05 -07:00
caternuson
3736ebfde1 refactor for better sw spi only support 2022-08-22 15:18:26 -07:00
Eva Herrada
e89ae64bd3
Bump to 1.13.2 2022-08-12 17:16:53 -04:00
Limor "Ladyada" Fried
4b8f6e312c
Merge pull request #106 from RobTillaart/master
Fix #105 - make I2C setspeed more robust
2022-08-12 15:06:06 -04:00
rob tillaart
319d44c093 fix build 2022-08-08 22:02:39 +02:00
rob tillaart
e238822921 clang-format 2022-08-08 21:31:17 +02:00
Rob Tillaart
3cc0846d78
Fix #105 - make setspeed more robust
- prevent out of range I2C speeds for AVR
2022-08-08 21:17:42 +02:00
Eva Herrada
8fce6cda99
Bump to 1.13.1 2022-08-02 12:26:14 -04:00
lady ada
5c159aa9a1 oi nevermind 2022-08-02 11:23:11 -04:00
lady ada
0e5b03fcfb clang 2022-08-02 11:11:30 -04:00
lady ada
fe6bb61052 Merge branch 'master' of github.com:adafruit/Adafruit_BusIO 2022-08-02 11:06:54 -04:00
lady ada
a8b7958a1a be more specific on fixing arduino i2c speeds 2022-08-02 11:06:49 -04:00
Eva Herrada
eeda9eeee2
Bump to 1.13.0 2022-08-01 13:40:43 -04:00
lady ada
a493f3d7a3 clang 2022-07-31 23:26:58 -04:00
lady ada
8c7a20af42 Merge branch 'master' of github.com:adafruit/Adafruit_BusIO 2022-07-31 23:25:28 -04:00
lady ada
399aeea376 https://github.com/adafruit/Adafruit_BusIO/issues/100 2022-07-31 23:25:24 -04:00
Limor "Ladyada" Fried
23ac286bd0
Merge pull request #104 from adafruit/fixavrsetspeed
manually handle AVR i2c setspeed to handle slow clocks
2022-07-31 17:46:19 -04:00
lady ada
3e0e740d56 clang 2022-07-31 17:06:55 -04:00
lady ada
36da2e4611 prescaler is not calculated here https://github.com/arduino/ArduinoCore-avr/blob/master/libraries/Wire/src/utility/twi.c#L139 which means we cannot get below 30.5mhz! 2022-07-31 17:04:44 -04:00
Eva Herrada
c421326131
Bump to 1.12.0 2022-06-28 16:19:19 -04:00
lady ada
1cb88a65b7 add ESP32 large buffer support (doesnt fix bno085 but worth a short)
cc @caternuson
2022-06-25 21:12:11 -04:00
Eva Herrada
515f63f49c
Bump to 1.11.6 2022-05-09 15:56:03 -04:00
Limor "Ladyada" Fried
bb7c77ad09
Merge pull request #95 from eringerli/workflow
updated github workflow
2022-05-02 18:29:58 -04:00
Limor "Ladyada" Fried
02665fd93f
Merge pull request #96 from KurtE/t4x_neutered
T4.x - Software SPI - don't use FAST_PINIO
2022-05-02 18:29:41 -04:00
Limor "Ladyada" Fried
b949d28bde
Merge pull request #93 from eringerli/cs-transaction-management
better transaction management
2022-05-02 18:29:00 -04:00
KurtE
17cf18bf5b T4.x - Software SPI - don't use FAST_PINIO
The original problem was that the code defined the registers and mask as 8 bits, when the T4.x ones are 32 bits.  So it only worked on a subset of pins.

So first fix would be to simply define these values as 32 bits.  But doing so leaves you code at risk as the Set/Clear code in this library is not atomic,
Example: *clkPort |= clkPinMask;

So if something happens in the small time window after the time the register is retrieved and then manipulated and written back, such as an interrupt.
Or maybe if other hardware is driving the pin.  These changes would be
clobbered by the above code.

Not sure how many other boards (if any) may be hit by the same issue.

It is not an issue with T3.x as the Teensy code uses the M3/M4 bitband support, so for each pin there is a unique memory address for it and these operations are atomic.

Note: the Arm M7 does not support bitbands.  However  in these caseAtomic code can be written for the T4.x by instead using the DR register of the IO port, you use the DR_SET, DR_CLEAR, DR_TOGGLE registers instead which do as the names imply
the do that operation only those pins who have a 1 bit set to the value...
2022-05-02 15:16:52 -07:00
Eva Herrada
204c1de9ab
Bump to 1.11.5 2022-05-02 17:50:30 -04:00
Christian Riggenbach
f82f699c64 reuse beginTransactionWithAssertingCS()/endTransactionWithDeassertingCS() 2022-05-02 22:37:27 +02:00
Christian Riggenbach
c00ec13218 moved setChipSelect() in front of beginTransactionWithAssertingCS()
This is a more logical order, as beginTransactionWithAssertingCS() and
endTransactionWithDeassertingCS() both call it.
2022-05-02 22:37:17 +02:00
Christian Riggenbach
41635e3c68 beginTransactionWithAssertingCS() and endTransactionWithDeassertingCS()
These two methods are similar to beginTransaction() and endTransaction(),
but, as the name implies, with CS management. They are both public, as
beginTransaction() and endTransaction() are too.
2022-05-02 22:35:38 +02:00
Christian Riggenbach
132124b093 updated github workflow 2022-05-02 22:12:18 +02:00
Limor "Ladyada" Fried
4ca049393f
Merge pull request #92 from eringerli/more-specific-documentation
More specific Documentation
2022-05-02 16:11:36 -04:00
Christian Riggenbach
a43f6e0921 more specific documentation 2022-05-02 20:57:10 +02:00
Eva Herrada
87af677566
Bump to 1.11.4 2022-04-25 15:18:37 -04:00
Limor "Ladyada" Fried
c702120651
Merge pull request #89 from eringerli/cleanup
Cleanup
2022-04-17 18:09:39 -04:00
Christian Riggenbach
4b18d396dc use the typesafe replacement nullptr instead of NULL (since C++11) 2022-04-17 15:03:17 +02:00
Christian Riggenbach
3561fd9ff6 delete works for nullptr, no need to set a member in the destructor 2022-04-17 14:43:57 +02:00
Eva Herrada
1c1c73ee85
Bump to 1.11.3 2022-03-17 11:05:04 -04:00
Ha Thach
ef3d84faa8
Merge pull request #84 from yilungao/spi-write-param-const-ness
write method parameter const-ness
2022-03-15 22:09:42 +07:00
Walt
b6f7b3abe1 applied clang-format 2022-03-14 22:45:53 -07:00
Walt
c41e829dcc write method parameter const-ness
fix https://github.com/adafruit/Adafruit_FRAM_SPI/issues/25
2022-03-10 21:43:30 -08:00
Carter Nelson
1741708a6a
Update library.properties 2022-03-01 06:58:02 -08:00
Limor "Ladyada" Fried
538b07a070
Merge pull request #83 from adafruit/revert-77-master
Revert "Faster hardware SPI writes on SAMD"
2022-02-28 21:06:36 -05:00
Carter Nelson
9bef46eeba
Revert "Faster hardware SPI writes on SAMD" 2022-02-28 17:38:40 -08:00
Eva Herrada
12e4ddb6e0
Bump to 1.11.1 2022-02-10 15:34:16 -05:00
Limor "Ladyada" Fried
512fde07b5
Merge pull request #77 from monroewilliams/master
Faster hardware SPI writes on SAMD
2022-02-02 16:23:57 -05:00
Eva Herrada
92b460c3f4
Bump to 1.11.0 2022-01-31 15:35:59 -05:00
Limor "Ladyada" Fried
afbd408d17
Merge pull request #79 from EBD232/master
Add support for Heltec CubeCell modules with ASR6502
2022-01-26 01:06:07 -05:00
Carter Nelson
6b3e7a3374
Update library.properties 2022-01-24 19:31:14 -08:00
Limor "Ladyada" Fried
b689ae60a2
Merge pull request #80 from caternuson/no_cs
Refinements for no CS configs
2022-01-24 21:17:42 -05:00
caternuson
7961058057 refinements for no CS configs 2022-01-24 16:56:58 -08:00
Eva Herrada
7a05fccacb
Bump to 1.10.2 2022-01-24 12:08:34 -05:00
Erik Backlund
5e12460a55 Add support for Heltec CubeCell modules with ASR6502 2022-01-22 18:14:58 +01:00
Monroe Williams
5efa09dbe7 Comment formatting. 2022-01-21 18:28:04 -08:00
Monroe Williams
67bd6e7db5 Add a hack to work around the differences between the Adafruit SAMD core and the official Arduino SAMD core. 2022-01-21 18:12:50 -08:00
Limor "Ladyada" Fried
a740ebdbea
Merge pull request #78 from solhuebner/solhuebner-ESP-IDF
Enable Adafruit_BusIO as ESP-IDF component support
2022-01-20 19:54:42 -05:00
Sol Huebner
b830b3c3d7
Enable Adafruit_BusIO as ESP-IDF component support
Enables Adafruit_BusIO as ESP-IDF component support (with Arduino as component)
2022-01-16 01:27:10 +01:00
Monroe Williams
7f66a34b9c In the Adafruit_SPIDevice class, when running on the SAMD architecture in the hardware SPI case, use the SPIClass::transfer(txbuf, rxbuf, count, block) method when writing instead of looping over individual bytes.
This makes use of DMA and is noticeably faster.
2022-01-13 19:23:05 -08:00
Eva Herrada
69b929d400
1.10.1 2022-01-12 18:06:19 -05:00
Limor "Ladyada" Fried
edd38996a1
Merge pull request #76 from monroewilliams/master
Faster hardware SPI writes on ESP32
2022-01-12 13:47:24 -05:00
Monroe Williams
3bdfee4ab8 In the Adafruit_SPIDevice class, when running on ESP32 in the hardware SPI case, use the SPIClass::transferBytes() method when writing instead of looping over individual bytes.
This makes use of the hardware fifo buffers and is noticeably faster.
2022-01-12 00:33:47 -08:00
Eva Herrada
ea1e1a833c
Bump to 1.10.0 2022-01-03 16:44:03 -05:00
Limor "Ladyada" Fried
33ff0c4bbc
Merge pull request #75 from eringerli/master
added write_and_read()
2021-12-31 13:27:33 -05:00
Christian Riggenbach
c43e0ae83e added write_and_read()
This method adds a wrapper for transfer() with CS-pin and
transaction management
2021-12-31 11:32:36 +01:00
Eva Herrada
9c5fcb76d6
Bump to 1.9.9 2021-12-20 22:58:00 -05:00
Carter Nelson
649bc9f93c
Merge pull request #73 from slaff/fix/spelling
Fixed small spelling mistakes.
2021-12-10 08:38:25 -08:00
Slavey Karadzhov
570d172764 Fixed small spelling mistakes. 2021-12-10 10:12:37 +01:00
Ha Thach
bbd2fd63af
increase version to 1.9.8 2021-11-26 13:55:14 +07:00
Ha Thach
690da23a8d
Merge pull request #70 from adafruit/fix-32u
Fix 32u with Wire end()
2021-11-26 13:53:59 +07:00
hathach
44618da5a6 temporarily skip end() for esp32 arch 2021-11-26 13:28:12 +07:00
hathach
389f4cd417 clang 2021-11-26 12:44:53 +07:00
hathach
8b26deb581 fix 32u4 which is avr core without WIRE_HAS_END 2021-11-26 11:37:29 +07:00
hathach
7b97d0de31 add feather32u4 to ci build 2021-11-26 10:01:51 +07:00
Ha Thach
9b8e3d5aed
increase version to 1.9.7 2021-11-24 23:08:15 +07:00
Ha Thach
e5c99032f5
Merge pull request #68 from adafruit/add-end
add end() to de-init i2c peripheral
2021-11-24 22:58:07 +07:00
hathach
5d6fa8dfaf fix doxygen 2021-11-24 18:05:49 +07:00
hathach
6804a451b3 skip wire end() for ESP8266 2021-11-24 17:55:52 +07:00
hathach
a2befb15de add end() to de-init i2c peripheral 2021-11-24 14:10:05 +07:00
lady ada
8b0ccda6bd ckag 2021-11-20 01:09:02 -05:00
lady ada
02ca544bf8 one more 2021-11-20 00:58:11 -05:00
lady ada
2953071b1e bump 2021-11-20 00:56:45 -05:00
lady ada
3feb7f9690 add more arduinoh 2021-11-20 00:56:35 -05:00
Paint Your Dragon
170ff5f726
Bump version for posterity
Changes are cosmetic, not functional. Clarify the hierarchy of #includes among various files.
2021-11-19 12:12:29 -08:00
Phillip Burgess
cc1fd93f02 No functional change, cleaning up shotgun-style #includes 2021-11-19 12:00:35 -08:00
Paint Your Dragon
767a0664c8
Bump to 1.9.4 for Zero TwoWire changes 2021-11-17 14:05:44 -08:00
lady ada
bdc5780099 klnax 2021-11-17 14:42:18 -05:00
lady ada
9a525b2ba3 try carter's fix1 2021-11-17 14:22:19 -05:00
lady ada
106018df52 oof 2021-11-17 14:02:01 -05:00
lady ada
76bcd63f18 try to change namespace? 2021-11-17 13:46:59 -05:00
lady ada
86cb7eefc8 Merge branch 'master' of github.com:adafruit/Adafruit_BusIO 2021-09-29 13:13:06 -04:00
Carter Nelson
da6809b582
Merge pull request #67 from caternuson/bus_conditionals
Fix SPI preproc guards
2021-09-28 15:24:13 -07:00
caternuson
4ccef6ae19 revert register logic 2021-09-28 15:11:01 -07:00
caternuson
6ffc223ad3 clang 2021-09-28 14:41:43 -07:00
caternuson
c6965bd471 selectively remove spi 2021-09-28 14:31:23 -07:00
caternuson
a819f24d00 fix spi preproc guards 2021-09-28 12:15:40 -07:00
Carter Nelson
cb21cf5979
Merge pull request #65 from caternuson/busio_better_chunk
Update chunk
2021-09-27 12:15:59 -07:00
caternuson
418887036b add parens 2021-09-27 12:04:14 -07:00
caternuson
398210be46 update chunk 2021-09-27 11:26:21 -07:00
ladyada
b6c594e549 Merge branch 'master' of github.com:adafruit/Adafruit_BusIO 2021-08-24 17:15:49 -04:00
ladyada
9dbed68a15 add som taaaaaaaaaabs 2021-08-24 17:15:45 -04:00
Carter Nelson
b903c7e015
Update library.properties 2021-08-22 11:06:27 -07:00
Carter Nelson
c5a6884d44
Merge pull request #62 from caternuson/iss61
Fix chunks
2021-08-22 11:06:06 -07:00
caternuson
134eabfedf fix chunk 2021-08-21 12:49:24 -07:00
Carter Nelson
34f7392493
Merge pull request #59 from caternuson/iss58_chunk
Chunkify I2C
2021-08-11 08:12:47 -07:00
caternuson
96b1b42ec5 chunkify i2c 2021-08-10 15:19:04 -07:00
Dylan Herrada
8ea6efe473
Bump to 1.8.3 2021-07-22 11:38:02 -04:00
Limor "Ladyada" Fried
14f6a3940b
Merge pull request #56 from adafruit/renamebitorder
Renamebitorder
2021-07-17 16:18:34 -04:00
lady ada
d33a16468f fix for samd 2021-07-17 16:09:09 -04:00
lady ada
8ad008a699 fix busorder enum to deal with arc32 2021-07-17 15:54:07 -04:00
Dylan Herrada
0ba57611c6
Bump to 1.8.2 2021-07-06 13:20:38 -04:00
Limor "Ladyada" Fried
9af34a0a8f
Merge pull request #51 from adafruit/tiny8
Tiny8
2021-07-01 12:04:20 -04:00
ladyada
f28f3ae7f0 clang 2021-07-01 11:40:28 -04:00
ladyada
63853d619d ah skip it 2021-06-30 17:18:10 -04:00
ladyada
f1da832667 remove some warnings 2021-06-30 17:15:13 -04:00
ladyada
be51ea62c6 tpzo 2021-06-30 17:00:23 -04:00
ladyada
05398d9395 add trinket/attiny8 support 2021-06-30 16:46:43 -04:00
Carter Nelson
1bd76737a2
Update library.properties 2021-06-25 10:17:42 -07:00
Carter Nelson
40cc4e18b0
Merge pull request #50 from adafruit/mcpreg
Add new SPI register type
2021-06-25 09:32:55 -07:00
26 changed files with 1151 additions and 327 deletions

View file

@ -7,26 +7,27 @@ jobs:
runs-on: ubuntu-latest
steps:
- uses: actions/setup-python@v1
- uses: actions/setup-python@v4
with:
python-version: '3.x'
- uses: actions/checkout@v2
- uses: actions/checkout@v2
- uses: actions/checkout@v3
- uses: actions/checkout@v3
with:
repository: adafruit/ci-arduino
path: ci
- name: pre-install
- name: Install the prerequisites
run: bash ci/actions_install.sh
- name: test platforms
run: python3 ci/build_platform.py main_platforms
- name: Check for correct code formatting with clang-format
run: python3 ci/run-clang-format.py -e "ci/*" -e "bin/*" -r .
- name: clang
run: python3 ci/run-clang-format.py -e "ci/*" -e "bin/*" -r .
- name: doxygen
- name: Check for correct documentation with doxygen
env:
GH_REPO_TOKEN: ${{ secrets.GH_REPO_TOKEN }}
PRETTYNAME : "Adafruit Bus IO Library"
run: bash ci/doxy_gen_and_deploy.sh
- name: Test the code on supported platforms
run: python3 ci/build_platform.py main_platforms zero feather32u4

View file

@ -1,5 +1,8 @@
#include <Adafruit_BusIO_Register.h>
#if !defined(SPI_INTERFACES_COUNT) || \
(defined(SPI_INTERFACES_COUNT) && (SPI_INTERFACES_COUNT > 0))
/*!
* @brief Create a register we access over an I2C Device (which defines the
* bus and address)
@ -18,7 +21,7 @@ Adafruit_BusIO_Register::Adafruit_BusIO_Register(Adafruit_I2CDevice *i2cdevice,
uint8_t byteorder,
uint8_t address_width) {
_i2cdevice = i2cdevice;
_spidevice = NULL;
_spidevice = nullptr;
_addrwidth = address_width;
_address = reg_addr;
_byteorder = byteorder;
@ -47,7 +50,7 @@ Adafruit_BusIO_Register::Adafruit_BusIO_Register(Adafruit_SPIDevice *spidevice,
uint8_t address_width) {
_spidevice = spidevice;
_spiregtype = type;
_i2cdevice = NULL;
_i2cdevice = nullptr;
_addrwidth = address_width;
_address = reg_addr;
_byteorder = byteorder;
@ -56,12 +59,12 @@ Adafruit_BusIO_Register::Adafruit_BusIO_Register(Adafruit_SPIDevice *spidevice,
/*!
* @brief Create a register we access over an I2C or SPI Device. This is a
* handy function because we can pass in NULL for the unused interface, allowing
* libraries to mass-define all the registers
* @param i2cdevice The I2CDevice to use for underlying I2C access, if NULL
* we use SPI
* @param spidevice The SPIDevice to use for underlying SPI access, if NULL
* we use I2C
* handy function because we can pass in nullptr for the unused interface,
* allowing libraries to mass-define all the registers
* @param i2cdevice The I2CDevice to use for underlying I2C access, if
* nullptr we use SPI
* @param spidevice The SPIDevice to use for underlying SPI access, if
* nullptr we use I2C
* @param reg_addr The address pointer value for the I2C/SMBus/SPI register,
* can be 8 or 16 bits
* @param type The method we use to read/write data to SPI (which is not
@ -85,6 +88,26 @@ Adafruit_BusIO_Register::Adafruit_BusIO_Register(
_width = width;
}
/*!
* @brief Create a register we access over a GenericDevice
* @param genericdevice Generic device to use
* @param reg_addr Register address we will read/write
* @param width Width of the register in bytes (1-4)
* @param byteorder Byte order of register data (LSBFIRST or MSBFIRST)
* @param address_width Width of the register address in bytes (1 or 2)
*/
Adafruit_BusIO_Register::Adafruit_BusIO_Register(
Adafruit_GenericDevice *genericdevice, uint16_t reg_addr, uint8_t width,
uint8_t byteorder, uint8_t address_width) {
_i2cdevice = nullptr;
_spidevice = nullptr;
_genericdevice = genericdevice;
_addrwidth = address_width;
_address = reg_addr;
_byteorder = byteorder;
_width = width;
}
/*!
* @brief Write a buffer of data to the register location
* @param buffer Pointer to data to write
@ -93,17 +116,14 @@ Adafruit_BusIO_Register::Adafruit_BusIO_Register(
* uncheckable)
*/
bool Adafruit_BusIO_Register::write(uint8_t *buffer, uint8_t len) {
uint8_t addrbuffer[2] = {(uint8_t)(_address & 0xFF),
(uint8_t)(_address >> 8)};
if (_i2cdevice) {
return _i2cdevice->write(buffer, len, true, addrbuffer, _addrwidth);
}
if (_spidevice) {
if (_spiregtype == ADDRESSED_OPCODE_BIT0_LOW_TO_WRITE) {
// very special case!
// pass the special opcode address which we set as the high byte of the
// regaddr
addrbuffer[0] =
@ -113,7 +133,6 @@ bool Adafruit_BusIO_Register::write(uint8_t *buffer, uint8_t len) {
// the address appears to be a byte longer
return _spidevice->write(buffer, len, addrbuffer, _addrwidth + 1);
}
if (_spiregtype == ADDRBIT8_HIGH_TOREAD) {
addrbuffer[0] &= ~0x80;
}
@ -126,6 +145,9 @@ bool Adafruit_BusIO_Register::write(uint8_t *buffer, uint8_t len) {
}
return _spidevice->write(buffer, len, addrbuffer, _addrwidth);
}
if (_genericdevice) {
return _genericdevice->writeRegister(addrbuffer, _addrwidth, buffer, len);
}
return false;
}
@ -189,23 +211,20 @@ uint32_t Adafruit_BusIO_Register::read(void) {
uint32_t Adafruit_BusIO_Register::readCached(void) { return _cached; }
/*!
* @brief Read a buffer of data from the register location
* @param buffer Pointer to data to read into
* @param len Number of bytes to read
* @return True on successful write (only really useful for I2C as SPI is
* uncheckable)
*/
@brief Read a number of bytes from a register into a buffer
@param buffer Buffer to read data into
@param len Number of bytes to read into the buffer
@return true on successful read, otherwise false
*/
bool Adafruit_BusIO_Register::read(uint8_t *buffer, uint8_t len) {
uint8_t addrbuffer[2] = {(uint8_t)(_address & 0xFF),
(uint8_t)(_address >> 8)};
if (_i2cdevice) {
return _i2cdevice->write_then_read(addrbuffer, _addrwidth, buffer, len);
}
if (_spidevice) {
if (_spiregtype == ADDRESSED_OPCODE_BIT0_LOW_TO_WRITE) {
// very special case!
// pass the special opcode address which we set as the high byte of the
// regaddr
addrbuffer[0] =
@ -227,6 +246,9 @@ bool Adafruit_BusIO_Register::read(uint8_t *buffer, uint8_t len) {
}
return _spidevice->write_then_read(addrbuffer, _addrwidth, buffer, len);
}
if (_genericdevice) {
return _genericdevice->readRegister(addrbuffer, _addrwidth, buffer, len);
}
return false;
}
@ -358,3 +380,5 @@ void Adafruit_BusIO_Register::setAddress(uint16_t address) {
void Adafruit_BusIO_Register::setAddressWidth(uint16_t address_width) {
_addrwidth = address_width;
}
#endif // SPI exists

View file

@ -1,10 +1,15 @@
#include <Adafruit_I2CDevice.h>
#include <Adafruit_SPIDevice.h>
#include <Arduino.h>
#ifndef Adafruit_BusIO_Register_h
#define Adafruit_BusIO_Register_h
#include <Arduino.h>
#if !defined(SPI_INTERFACES_COUNT) || \
(defined(SPI_INTERFACES_COUNT) && (SPI_INTERFACES_COUNT > 0))
#include <Adafruit_GenericDevice.h>
#include <Adafruit_I2CDevice.h>
#include <Adafruit_SPIDevice.h>
typedef enum _Adafruit_BusIO_SPIRegType {
ADDRBIT8_HIGH_TOREAD = 0,
/*!<
@ -53,6 +58,11 @@ public:
uint8_t width = 1, uint8_t byteorder = LSBFIRST,
uint8_t address_width = 1);
Adafruit_BusIO_Register(Adafruit_GenericDevice *genericdevice,
uint16_t reg_addr, uint8_t width = 1,
uint8_t byteorder = LSBFIRST,
uint8_t address_width = 1);
bool read(uint8_t *buffer, uint8_t len);
bool read(uint8_t *value);
bool read(uint16_t *value);
@ -73,10 +83,11 @@ public:
private:
Adafruit_I2CDevice *_i2cdevice;
Adafruit_SPIDevice *_spidevice;
Adafruit_GenericDevice *_genericdevice;
Adafruit_BusIO_SPIRegType _spiregtype;
uint16_t _address;
uint8_t _width, _addrwidth, _byteorder;
uint8_t _buffer[4]; // we wont support anything larger than uint32 for
uint8_t _buffer[4]; // we won't support anything larger than uint32 for
// non-buffered read
uint32_t _cached = 0;
};
@ -97,4 +108,5 @@ private:
uint8_t _bits, _shift;
};
#endif // SPI exists
#endif // BusIO_Register_h

View file

@ -0,0 +1,90 @@
/*
Written with help by Claude!
https://claude.ai/chat/335f50b1-3dd8-435e-9139-57ec7ca26a3c (at this time
chats are not shareable :(
*/
#include "Adafruit_GenericDevice.h"
/*!
* @brief Create a Generic device with the provided read/write functions
* @param obj Pointer to object instance
* @param read_func Function pointer for reading raw data
* @param write_func Function pointer for writing raw data
* @param readreg_func Function pointer for reading registers (optional)
* @param writereg_func Function pointer for writing registers (optional) */
Adafruit_GenericDevice::Adafruit_GenericDevice(
void *obj, busio_genericdevice_read_t read_func,
busio_genericdevice_write_t write_func,
busio_genericdevice_readreg_t readreg_func,
busio_genericdevice_writereg_t writereg_func) {
_obj = obj;
_read_func = read_func;
_write_func = write_func;
_readreg_func = readreg_func;
_writereg_func = writereg_func;
_begun = false;
}
/*! @brief Simple begin function (doesn't do much at this time)
@return true always
*/
bool Adafruit_GenericDevice::begin(void) {
_begun = true;
return true;
}
/*!
@brief Marks the GenericDevice as no longer in use.
@note: Since this is a GenericDevice, if you are using this with a Serial
object, this does NOT disable serial communication or release the RX/TX pins.
That must be done manually by calling Serial.end().
*/
void Adafruit_GenericDevice::end(void) { _begun = false; }
/*! @brief Write a buffer of data
@param buffer Pointer to buffer of data to write
@param len Number of bytes to write
@return true if write was successful, otherwise false */
bool Adafruit_GenericDevice::write(const uint8_t *buffer, size_t len) {
if (!_begun)
return false;
return _write_func(_obj, buffer, len);
}
/*! @brief Read data into a buffer
@param buffer Pointer to buffer to read data into
@param len Number of bytes to read
@return true if read was successful, otherwise false */
bool Adafruit_GenericDevice::read(uint8_t *buffer, size_t len) {
if (!_begun)
return false;
return _read_func(_obj, buffer, len);
}
/*! @brief Read from a register location
@param addr_buf Buffer containing register address
@param addrsiz Size of register address in bytes
@param buf Buffer to store read data
@param bufsiz Size of data to read in bytes
@return true if read was successful, otherwise false */
bool Adafruit_GenericDevice::readRegister(uint8_t *addr_buf, uint8_t addrsiz,
uint8_t *buf, uint16_t bufsiz) {
if (!_begun || !_readreg_func)
return false;
return _readreg_func(_obj, addr_buf, addrsiz, buf, bufsiz);
}
/*! @brief Write to a register location
@param addr_buf Buffer containing register address
@param addrsiz Size of register address in bytes
@param buf Buffer containing data to write
@param bufsiz Size of data to write in bytes
@return true if write was successful, otherwise false */
bool Adafruit_GenericDevice::writeRegister(uint8_t *addr_buf, uint8_t addrsiz,
const uint8_t *buf,
uint16_t bufsiz) {
if (!_begun || !_writereg_func)
return false;
return _writereg_func(_obj, addr_buf, addrsiz, buf, bufsiz);
}

56
Adafruit_GenericDevice.h Normal file
View file

@ -0,0 +1,56 @@
#ifndef ADAFRUIT_GENERICDEVICE_H
#define ADAFRUIT_GENERICDEVICE_H
#include <Arduino.h>
typedef bool (*busio_genericdevice_read_t)(void *obj, uint8_t *buffer,
size_t len);
typedef bool (*busio_genericdevice_write_t)(void *obj, const uint8_t *buffer,
size_t len);
typedef bool (*busio_genericdevice_readreg_t)(void *obj, uint8_t *addr_buf,
uint8_t addrsiz, uint8_t *data,
uint16_t datalen);
typedef bool (*busio_genericdevice_writereg_t)(void *obj, uint8_t *addr_buf,
uint8_t addrsiz,
const uint8_t *data,
uint16_t datalen);
/*!
* @brief Class for communicating with a device via generic read/write functions
*/
class Adafruit_GenericDevice {
public:
Adafruit_GenericDevice(
void *obj, busio_genericdevice_read_t read_func,
busio_genericdevice_write_t write_func,
busio_genericdevice_readreg_t readreg_func = nullptr,
busio_genericdevice_writereg_t writereg_func = nullptr);
bool begin(void);
void end(void);
bool read(uint8_t *buffer, size_t len);
bool write(const uint8_t *buffer, size_t len);
bool readRegister(uint8_t *addr_buf, uint8_t addrsiz, uint8_t *buf,
uint16_t bufsiz);
bool writeRegister(uint8_t *addr_buf, uint8_t addrsiz, const uint8_t *buf,
uint16_t bufsiz);
protected:
/*! @brief Function pointer for reading raw data from the device */
busio_genericdevice_read_t _read_func;
/*! @brief Function pointer for writing raw data to the device */
busio_genericdevice_write_t _write_func;
/*! @brief Function pointer for reading a 'register' from the device */
busio_genericdevice_readreg_t _readreg_func;
/*! @brief Function pointer for writing a 'register' to the device */
busio_genericdevice_writereg_t _writereg_func;
bool _begun; ///< whether we have initialized yet (in case the function needs
///< to do something)
private:
void *_obj; ///< Pointer to object instance
};
#endif // ADAFRUIT_GENERICDEVICE_H

View file

@ -1,7 +1,6 @@
#include <Adafruit_I2CDevice.h>
#include <Arduino.h>
#include "Adafruit_I2CDevice.h"
//#define DEBUG_SERIAL Serial
// #define DEBUG_SERIAL Serial
/*!
* @brief Create an I2C device at a given address
@ -14,6 +13,8 @@ Adafruit_I2CDevice::Adafruit_I2CDevice(uint8_t addr, TwoWire *theWire) {
_begun = false;
#ifdef ARDUINO_ARCH_SAMD
_maxBufferSize = 250; // as defined in Wire.h's RingBuffer
#elif defined(ESP32)
_maxBufferSize = I2C_BUFFER_LENGTH;
#else
_maxBufferSize = 32;
#endif
@ -22,8 +23,8 @@ Adafruit_I2CDevice::Adafruit_I2CDevice(uint8_t addr, TwoWire *theWire) {
/*!
* @brief Initializes and does basic address detection
* @param addr_detect Whether we should attempt to detect the I2C address
* with a scan. 99% of sensors/devices don't mind but once in a while, they spaz
* on a scan!
* with a scan. 99% of sensors/devices don't mind, but once in a while they
* don't respond well to a scan!
* @return True if I2C initialized and a device with the addr found
*/
bool Adafruit_I2CDevice::begin(bool addr_detect) {
@ -36,6 +37,23 @@ bool Adafruit_I2CDevice::begin(bool addr_detect) {
return true;
}
/*!
* @brief De-initialize device, turn off the Wire interface
*/
void Adafruit_I2CDevice::end(void) {
// Not all port implement Wire::end(), such as
// - ESP8266
// - AVR core without WIRE_HAS_END
// - ESP32: end() is implemented since 2.0.1 which is latest at the moment.
// Temporarily disable for now to give time for user to update.
#if !(defined(ESP8266) || \
(defined(ARDUINO_ARCH_AVR) && !defined(WIRE_HAS_END)) || \
defined(ARDUINO_ARCH_ESP32))
_wire->end();
_begun = false;
#endif
}
/*!
* @brief Scans I2C for the address - note will give a false-positive
* if there's no pullups on I2C
@ -49,9 +67,22 @@ bool Adafruit_I2CDevice::detected(void) {
// A basic scanner, see if it ACK's
_wire->beginTransmission(_addr);
#ifdef DEBUG_SERIAL
DEBUG_SERIAL.print(F("Address 0x"));
DEBUG_SERIAL.print(_addr, HEX);
#endif
#ifdef ARDUINO_ARCH_MBED
_wire->write(0); // forces a write request instead of a read
#endif
if (_wire->endTransmission() == 0) {
#ifdef DEBUG_SERIAL
DEBUG_SERIAL.println(F(" Detected"));
#endif
return true;
}
#ifdef DEBUG_SERIAL
DEBUG_SERIAL.println(F(" Not detected"));
#endif
return false;
}
@ -84,7 +115,7 @@ bool Adafruit_I2CDevice::write(const uint8_t *buffer, size_t len, bool stop,
_wire->beginTransmission(_addr);
// Write the prefix data (usually an address)
if ((prefix_len != 0) && (prefix_buffer != NULL)) {
if ((prefix_len != 0) && (prefix_buffer != nullptr)) {
if (_wire->write(prefix_buffer, prefix_len) != prefix_len) {
#ifdef DEBUG_SERIAL
DEBUG_SERIAL.println(F("\tI2CDevice failed to write"));
@ -106,7 +137,7 @@ bool Adafruit_I2CDevice::write(const uint8_t *buffer, size_t len, bool stop,
DEBUG_SERIAL.print(F("\tI2CWRITE @ 0x"));
DEBUG_SERIAL.print(_addr, HEX);
DEBUG_SERIAL.print(F(" :: "));
if ((prefix_len != 0) && (prefix_buffer != NULL)) {
if ((prefix_len != 0) && (prefix_buffer != nullptr)) {
for (uint16_t i = 0; i < prefix_len; i++) {
DEBUG_SERIAL.print(F("0x"));
DEBUG_SERIAL.print(prefix_buffer[i], HEX);
@ -121,21 +152,21 @@ bool Adafruit_I2CDevice::write(const uint8_t *buffer, size_t len, bool stop,
DEBUG_SERIAL.println();
}
}
DEBUG_SERIAL.println();
#endif
#ifdef DEBUG_SERIAL
// DEBUG_SERIAL.print("Stop: "); DEBUG_SERIAL.println(stop);
if (stop) {
DEBUG_SERIAL.print("\tSTOP");
}
#endif
if (_wire->endTransmission(stop) == 0) {
#ifdef DEBUG_SERIAL
DEBUG_SERIAL.println();
// DEBUG_SERIAL.println("Sent!");
#endif
return true;
} else {
#ifdef DEBUG_SERIAL
DEBUG_SERIAL.println("Failed to send!");
DEBUG_SERIAL.println("\tFailed to send!");
#endif
return false;
}
@ -150,17 +181,27 @@ bool Adafruit_I2CDevice::write(const uint8_t *buffer, size_t len, bool stop,
* @return True if read was successful, otherwise false.
*/
bool Adafruit_I2CDevice::read(uint8_t *buffer, size_t len, bool stop) {
if (len > maxBufferSize()) {
// currently not guaranteed to work if more than 32 bytes!
// we will need to find out if some platforms have larger
// I2C buffer sizes :/
#ifdef DEBUG_SERIAL
DEBUG_SERIAL.println(F("\tI2CDevice could not read such a large buffer"));
#endif
return false;
size_t pos = 0;
while (pos < len) {
size_t read_len =
((len - pos) > maxBufferSize()) ? maxBufferSize() : (len - pos);
bool read_stop = (pos < (len - read_len)) ? false : stop;
if (!_read(buffer + pos, read_len, read_stop))
return false;
pos += read_len;
}
return true;
}
bool Adafruit_I2CDevice::_read(uint8_t *buffer, size_t len, bool stop) {
#if defined(TinyWireM_h)
size_t recv = _wire->requestFrom((uint8_t)_addr, (uint8_t)len);
#elif defined(ARDUINO_ARCH_MEGAAVR)
size_t recv = _wire->requestFrom(_addr, len, stop);
#else
size_t recv = _wire->requestFrom((uint8_t)_addr, (uint8_t)len, (uint8_t)stop);
#endif
if (recv != len) {
// Not enough data available to fulfill our obligation!
#ifdef DEBUG_SERIAL
@ -227,10 +268,53 @@ uint8_t Adafruit_I2CDevice::address(void) { return _addr; }
* Not necessarily that the speed was achieved!
*/
bool Adafruit_I2CDevice::setSpeed(uint32_t desiredclk) {
#if (ARDUINO >= 157) && !defined(ARDUINO_STM32_FEATHER)
#if defined(__AVR_ATmega328__) || \
defined(__AVR_ATmega328P__) // fix arduino core set clock
// calculate TWBR correctly
if ((F_CPU / 18) < desiredclk) {
#ifdef DEBUG_SERIAL
Serial.println(F("I2C.setSpeed too high."));
#endif
return false;
}
uint32_t atwbr = ((F_CPU / desiredclk) - 16) / 2;
if (atwbr > 16320) {
#ifdef DEBUG_SERIAL
Serial.println(F("I2C.setSpeed too low."));
#endif
return false;
}
if (atwbr <= 255) {
atwbr /= 1;
TWSR = 0x0;
} else if (atwbr <= 1020) {
atwbr /= 4;
TWSR = 0x1;
} else if (atwbr <= 4080) {
atwbr /= 16;
TWSR = 0x2;
} else { // if (atwbr <= 16320)
atwbr /= 64;
TWSR = 0x3;
}
TWBR = atwbr;
#ifdef DEBUG_SERIAL
Serial.print(F("TWSR prescaler = "));
Serial.println(pow(4, TWSR));
Serial.print(F("TWBR = "));
Serial.println(atwbr);
#endif
return true;
#elif (ARDUINO >= 157) && !defined(ARDUINO_STM32_FEATHER) && \
!defined(TinyWireM_h)
_wire->setClock(desiredclk);
return true;
#else
(void)desiredclk;
return false;
#endif
}

View file

@ -1,19 +1,21 @@
#include <Wire.h>
#ifndef Adafruit_I2CDevice_h
#define Adafruit_I2CDevice_h
#include <Arduino.h>
#include <Wire.h>
///< The class which defines how we will talk to this device over I2C
class Adafruit_I2CDevice {
public:
Adafruit_I2CDevice(uint8_t addr, TwoWire *theWire = &Wire);
uint8_t address(void);
bool begin(bool addr_detect = true);
void end(void);
bool detected(void);
bool read(uint8_t *buffer, size_t len, bool stop = true);
bool write(const uint8_t *buffer, size_t len, bool stop = true,
const uint8_t *prefix_buffer = NULL, size_t prefix_len = 0);
const uint8_t *prefix_buffer = nullptr, size_t prefix_len = 0);
bool write_then_read(const uint8_t *write_buffer, size_t write_len,
uint8_t *read_buffer, size_t read_len,
bool stop = false);
@ -28,6 +30,7 @@ private:
TwoWire *_wire;
bool _begun;
size_t _maxBufferSize;
bool _read(uint8_t *buffer, size_t len, bool stop);
};
#endif // Adafruit_I2CDevice_h

View file

@ -1,7 +1,9 @@
#include "Adafruit_BusIO_Register.h"
#ifndef _ADAFRUIT_I2C_REGISTER_H_
#define _ADAFRUIT_I2C_REGISTER_H_
#include <Adafruit_BusIO_Register.h>
#include <Arduino.h>
typedef Adafruit_BusIO_Register Adafruit_I2CRegister;
typedef Adafruit_BusIO_RegisterBits Adafruit_I2CRegisterBits;

View file

@ -1,10 +1,9 @@
#include <Adafruit_SPIDevice.h>
#include <Arduino.h>
#include "Adafruit_SPIDevice.h"
//#define DEBUG_SERIAL Serial
// #define DEBUG_SERIAL Serial
/*!
* @brief Create an SPI device with the given CS pin and settins
* @brief Create an SPI device with the given CS pin and settings
* @param cspin The arduino pin number to use for chip select
* @param freq The SPI clock frequency to use, defaults to 1MHz
* @param dataOrder The SPI data order to use for bits within each byte,
@ -13,8 +12,9 @@
* @param theSPI The SPI bus to use, defaults to &theSPI
*/
Adafruit_SPIDevice::Adafruit_SPIDevice(int8_t cspin, uint32_t freq,
BitOrder dataOrder, uint8_t dataMode,
SPIClass *theSPI) {
BusIOBitOrder dataOrder,
uint8_t dataMode, SPIClass *theSPI) {
#ifdef BUSIO_HAS_HW_SPI
_cs = cspin;
_sck = _mosi = _miso = -1;
_spi = theSPI;
@ -23,10 +23,18 @@ Adafruit_SPIDevice::Adafruit_SPIDevice(int8_t cspin, uint32_t freq,
_freq = freq;
_dataOrder = dataOrder;
_dataMode = dataMode;
#else
// unused, but needed to suppress compiler warns
(void)cspin;
(void)freq;
(void)dataOrder;
(void)dataMode;
(void)theSPI;
#endif
}
/*!
* @brief Create an SPI device with the given CS pin and settins
* @brief Create an SPI device with the given CS pin and settings
* @param cspin The arduino pin number to use for chip select
* @param sckpin The arduino pin number to use for SCK
* @param misopin The arduino pin number to use for MISO, set to -1 if not
@ -40,7 +48,7 @@ Adafruit_SPIDevice::Adafruit_SPIDevice(int8_t cspin, uint32_t freq,
*/
Adafruit_SPIDevice::Adafruit_SPIDevice(int8_t cspin, int8_t sckpin,
int8_t misopin, int8_t mosipin,
uint32_t freq, BitOrder dataOrder,
uint32_t freq, BusIOBitOrder dataOrder,
uint8_t dataMode) {
_cs = cspin;
_sck = sckpin;
@ -66,18 +74,14 @@ Adafruit_SPIDevice::Adafruit_SPIDevice(int8_t cspin, int8_t sckpin,
_dataOrder = dataOrder;
_dataMode = dataMode;
_begun = false;
_spiSetting = new SPISettings(freq, dataOrder, dataMode);
_spi = NULL;
}
/*!
* @brief Release memory allocated in constructors
*/
Adafruit_SPIDevice::~Adafruit_SPIDevice() {
if (_spiSetting) {
if (_spiSetting)
delete _spiSetting;
_spiSetting = nullptr;
}
}
/*!
@ -86,11 +90,15 @@ Adafruit_SPIDevice::~Adafruit_SPIDevice() {
* init
*/
bool Adafruit_SPIDevice::begin(void) {
pinMode(_cs, OUTPUT);
digitalWrite(_cs, HIGH);
if (_cs != -1) {
pinMode(_cs, OUTPUT);
digitalWrite(_cs, HIGH);
}
if (_spi) { // hardware SPI
#ifdef BUSIO_HAS_HW_SPI
_spi->begin();
#endif
} else {
pinMode(_sck, OUTPUT);
@ -115,16 +123,19 @@ bool Adafruit_SPIDevice::begin(void) {
}
/*!
* @brief Transfer (send/receive) one byte over hard/soft SPI
* @brief Transfer (send/receive) a buffer over hard/soft SPI, without
* transaction management
* @param buffer The buffer to send and receive at the same time
* @param len The number of bytes to transfer
*/
void Adafruit_SPIDevice::transfer(uint8_t *buffer, size_t len) {
//
// HARDWARE SPI
//
if (_spi) {
// hardware SPI is easy
#ifdef BUSIO_HAS_HW_SPI
#if defined(SPARK)
_spi->transfer(buffer, buffer, len, NULL);
_spi->transfer(buffer, buffer, len, nullptr);
#elif defined(STM32)
for (size_t i = 0; i < len; i++) {
_spi->transfer(buffer[i]);
@ -133,8 +144,12 @@ void Adafruit_SPIDevice::transfer(uint8_t *buffer, size_t len) {
_spi->transfer(buffer, len);
#endif
return;
#endif
}
//
// SOFTWARE SPI
//
uint8_t startbit;
if (_dataOrder == SPI_BITORDER_LSBFIRST) {
startbit = 0x1;
@ -145,9 +160,7 @@ void Adafruit_SPIDevice::transfer(uint8_t *buffer, size_t len) {
bool towrite, lastmosi = !(buffer[0] & startbit);
uint8_t bitdelay_us = (1000000 / _freq) / 2;
// for softSPI we'll do it by hand
for (size_t i = 0; i < len; i++) {
// software SPI
uint8_t reply = 0;
uint8_t send = buffer[i];
@ -170,9 +183,9 @@ void Adafruit_SPIDevice::transfer(uint8_t *buffer, size_t len) {
if ((_mosi != -1) && (lastmosi != towrite)) {
#ifdef BUSIO_USE_FAST_PINIO
if (towrite)
*mosiPort |= mosiPinMask;
*mosiPort = *mosiPort | mosiPinMask;
else
*mosiPort &= ~mosiPinMask;
*mosiPort = *mosiPort & ~mosiPinMask;
#else
digitalWrite(_mosi, towrite);
#endif
@ -180,7 +193,7 @@ void Adafruit_SPIDevice::transfer(uint8_t *buffer, size_t len) {
}
#ifdef BUSIO_USE_FAST_PINIO
*clkPort |= clkPinMask; // Clock high
*clkPort = *clkPort | clkPinMask; // Clock high
#else
digitalWrite(_sck, HIGH);
#endif
@ -200,14 +213,14 @@ void Adafruit_SPIDevice::transfer(uint8_t *buffer, size_t len) {
}
#ifdef BUSIO_USE_FAST_PINIO
*clkPort &= ~clkPinMask; // Clock low
*clkPort = *clkPort & ~clkPinMask; // Clock low
#else
digitalWrite(_sck, LOW);
#endif
} else { // if (_dataMode == SPI_MODE1 || _dataMode == SPI_MODE3)
#ifdef BUSIO_USE_FAST_PINIO
*clkPort |= clkPinMask; // Clock high
*clkPort = *clkPort | clkPinMask; // Clock high
#else
digitalWrite(_sck, HIGH);
#endif
@ -219,16 +232,16 @@ void Adafruit_SPIDevice::transfer(uint8_t *buffer, size_t len) {
if (_mosi != -1) {
#ifdef BUSIO_USE_FAST_PINIO
if (send & b)
*mosiPort |= mosiPinMask;
*mosiPort = *mosiPort | mosiPinMask;
else
*mosiPort &= ~mosiPinMask;
*mosiPort = *mosiPort & ~mosiPinMask;
#else
digitalWrite(_mosi, send & b);
#endif
}
#ifdef BUSIO_USE_FAST_PINIO
*clkPort &= ~clkPinMask; // Clock low
*clkPort = *clkPort & ~clkPinMask; // Clock low
#else
digitalWrite(_sck, LOW);
#endif
@ -252,7 +265,8 @@ void Adafruit_SPIDevice::transfer(uint8_t *buffer, size_t len) {
}
/*!
* @brief Transfer (send/receive) one byte over hard/soft SPI
* @brief Transfer (send/receive) one byte over hard/soft SPI, without
* transaction management
* @param send The byte to send
* @return The byte received while transmitting
*/
@ -268,7 +282,9 @@ uint8_t Adafruit_SPIDevice::transfer(uint8_t send) {
*/
void Adafruit_SPIDevice::beginTransaction(void) {
if (_spi) {
#ifdef BUSIO_HAS_HW_SPI
_spi->beginTransaction(*_spiSetting);
#endif
}
}
@ -277,12 +293,45 @@ void Adafruit_SPIDevice::beginTransaction(void) {
*/
void Adafruit_SPIDevice::endTransaction(void) {
if (_spi) {
#ifdef BUSIO_HAS_HW_SPI
_spi->endTransaction();
#endif
}
}
/*!
* @brief Write a buffer or two to the SPI device.
* @brief Assert/Deassert the CS pin if it is defined
* @param value The state the CS is set to
*/
void Adafruit_SPIDevice::setChipSelect(int value) {
if (_cs != -1) {
digitalWrite(_cs, value);
}
}
/*!
* @brief Write a buffer or two to the SPI device, with transaction
* management.
* @brief Manually begin a transaction (calls beginTransaction if hardware
* SPI) with asserting the CS pin
*/
void Adafruit_SPIDevice::beginTransactionWithAssertingCS() {
beginTransaction();
setChipSelect(LOW);
}
/*!
* @brief Manually end a transaction (calls endTransaction if hardware SPI)
* with deasserting the CS pin
*/
void Adafruit_SPIDevice::endTransactionWithDeassertingCS() {
setChipSelect(HIGH);
endTransaction();
}
/*!
* @brief Write a buffer or two to the SPI device, with transaction
* management.
* @param buffer Pointer to buffer of data to write
* @param len Number of bytes from buffer to write
* @param prefix_buffer Pointer to optional array of data to write before
@ -291,29 +340,35 @@ void Adafruit_SPIDevice::endTransaction(void) {
* @return Always returns true because there's no way to test success of SPI
* writes
*/
bool Adafruit_SPIDevice::write(uint8_t *buffer, size_t len,
uint8_t *prefix_buffer, size_t prefix_len) {
if (_spi) {
_spi->beginTransaction(*_spiSetting);
}
bool Adafruit_SPIDevice::write(const uint8_t *buffer, size_t len,
const uint8_t *prefix_buffer,
size_t prefix_len) {
beginTransactionWithAssertingCS();
digitalWrite(_cs, LOW);
// do the writing
for (size_t i = 0; i < prefix_len; i++) {
transfer(prefix_buffer[i]);
}
for (size_t i = 0; i < len; i++) {
transfer(buffer[i]);
}
digitalWrite(_cs, HIGH);
#if defined(ARDUINO_ARCH_ESP32)
if (_spi) {
_spi->endTransaction();
if (prefix_len > 0) {
_spi->transferBytes((uint8_t *)prefix_buffer, nullptr, prefix_len);
}
if (len > 0) {
_spi->transferBytes((uint8_t *)buffer, nullptr, len);
}
} else
#endif
{
for (size_t i = 0; i < prefix_len; i++) {
transfer(prefix_buffer[i]);
}
for (size_t i = 0; i < len; i++) {
transfer(buffer[i]);
}
}
endTransactionWithDeassertingCS();
#ifdef DEBUG_SERIAL
DEBUG_SERIAL.print(F("\tSPIDevice Wrote: "));
if ((prefix_len != 0) && (prefix_buffer != NULL)) {
if ((prefix_len != 0) && (prefix_buffer != nullptr)) {
for (uint16_t i = 0; i < prefix_len; i++) {
DEBUG_SERIAL.print(F("0x"));
DEBUG_SERIAL.print(prefix_buffer[i], HEX);
@ -335,7 +390,8 @@ bool Adafruit_SPIDevice::write(uint8_t *buffer, size_t len,
}
/*!
* @brief Read from SPI into a buffer from the SPI device.
* @brief Read from SPI into a buffer from the SPI device, with transaction
* management.
* @param buffer Pointer to buffer of data to read into
* @param len Number of bytes from buffer to read.
* @param sendvalue The 8-bits of data to write when doing the data read,
@ -345,16 +401,10 @@ bool Adafruit_SPIDevice::write(uint8_t *buffer, size_t len,
*/
bool Adafruit_SPIDevice::read(uint8_t *buffer, size_t len, uint8_t sendvalue) {
memset(buffer, sendvalue, len); // clear out existing buffer
if (_spi) {
_spi->beginTransaction(*_spiSetting);
}
digitalWrite(_cs, LOW);
transfer(buffer, len);
digitalWrite(_cs, HIGH);
if (_spi) {
_spi->endTransaction();
}
beginTransactionWithAssertingCS();
transfer(buffer, len);
endTransactionWithDeassertingCS();
#ifdef DEBUG_SERIAL
DEBUG_SERIAL.print(F("\tSPIDevice Read: "));
@ -373,9 +423,9 @@ bool Adafruit_SPIDevice::read(uint8_t *buffer, size_t len, uint8_t sendvalue) {
}
/*!
* @brief Write some data, then read some data from SPI into another buffer.
* The buffers can point to same/overlapping locations. This does not
* transmit-receive at the same time!
* @brief Write some data, then read some data from SPI into another buffer,
* with transaction management. The buffers can point to same/overlapping
* locations. This does not transmit-receive at the same time!
* @param write_buffer Pointer to buffer of data to write from
* @param write_len Number of bytes from buffer to write.
* @param read_buffer Pointer to buffer of data to read into.
@ -385,17 +435,22 @@ bool Adafruit_SPIDevice::read(uint8_t *buffer, size_t len, uint8_t sendvalue) {
* @return Always returns true because there's no way to test success of SPI
* writes
*/
bool Adafruit_SPIDevice::write_then_read(uint8_t *write_buffer,
bool Adafruit_SPIDevice::write_then_read(const uint8_t *write_buffer,
size_t write_len, uint8_t *read_buffer,
size_t read_len, uint8_t sendvalue) {
if (_spi) {
_spi->beginTransaction(*_spiSetting);
}
digitalWrite(_cs, LOW);
beginTransactionWithAssertingCS();
// do the writing
for (size_t i = 0; i < write_len; i++) {
transfer(write_buffer[i]);
#if defined(ARDUINO_ARCH_ESP32)
if (_spi) {
if (write_len > 0) {
_spi->transferBytes((uint8_t *)write_buffer, nullptr, write_len);
}
} else
#endif
{
for (size_t i = 0; i < write_len; i++) {
transfer(write_buffer[i]);
}
}
#ifdef DEBUG_SERIAL
@ -429,11 +484,25 @@ bool Adafruit_SPIDevice::write_then_read(uint8_t *write_buffer,
DEBUG_SERIAL.println();
#endif
digitalWrite(_cs, HIGH);
if (_spi) {
_spi->endTransaction();
}
endTransactionWithDeassertingCS();
return true;
}
/*!
* @brief Write some data and read some data at the same time from SPI
* into the same buffer, with transaction management. This is basicaly a wrapper
* for transfer() with CS-pin and transaction management. This /does/
* transmit-receive at the same time!
* @param buffer Pointer to buffer of data to write/read to/from
* @param len Number of bytes from buffer to write/read.
* @return Always returns true because there's no way to test success of SPI
* writes
*/
bool Adafruit_SPIDevice::write_and_read(uint8_t *buffer, size_t len) {
beginTransactionWithAssertingCS();
transfer(buffer, len);
endTransactionWithDeassertingCS();
return true;
}

View file

@ -1,8 +1,19 @@
#include <SPI.h>
#ifndef Adafruit_SPIDevice_h
#define Adafruit_SPIDevice_h
#include <Arduino.h>
#if !defined(SPI_INTERFACES_COUNT) || \
(defined(SPI_INTERFACES_COUNT) && (SPI_INTERFACES_COUNT > 0))
// HW SPI available
#include <SPI.h>
#define BUSIO_HAS_HW_SPI
#else
// SW SPI ONLY
enum { SPI_MODE0, SPI_MODE1, SPI_MODE2, _SPI_MODE4 };
typedef uint8_t SPIClass;
#endif
// some modern SPI definitions don't have BitOrder enum
#if (defined(__AVR__) && !defined(ARDUINO_ARCH_MEGAAVR)) || \
defined(ESP8266) || defined(TEENSYDUINO) || defined(SPARK) || \
@ -11,28 +22,51 @@
defined(ARDUINO_AVR_ATmega4808) || defined(ARDUINO_AVR_ATmega3209) || \
defined(ARDUINO_AVR_ATmega3208) || defined(ARDUINO_AVR_ATmega1609) || \
defined(ARDUINO_AVR_ATmega1608) || defined(ARDUINO_AVR_ATmega809) || \
defined(ARDUINO_AVR_ATmega808)
defined(ARDUINO_AVR_ATmega808) || defined(ARDUINO_ARCH_ARC32) || \
defined(ARDUINO_ARCH_XMC)
typedef enum _BitOrder {
SPI_BITORDER_MSBFIRST = MSBFIRST,
SPI_BITORDER_LSBFIRST = LSBFIRST,
} BitOrder;
} BusIOBitOrder;
#elif defined(ESP32) || defined(__ASR6501__)
#elif defined(ESP32) || defined(__ASR6501__) || defined(__ASR6502__)
// some modern SPI definitions don't have BitOrder enum and have different SPI
// mode defines
typedef enum _BitOrder {
SPI_BITORDER_MSBFIRST = SPI_MSBFIRST,
SPI_BITORDER_LSBFIRST = SPI_LSBFIRST,
} BitOrder;
} BusIOBitOrder;
#else
// Some platforms have a BitOrder enum but its named MSBFIRST/LSBFIRST
#define SPI_BITORDER_MSBFIRST MSBFIRST
#define SPI_BITORDER_LSBFIRST LSBFIRST
typedef BitOrder BusIOBitOrder;
#endif
#if defined(__AVR__) || defined(TEENSYDUINO)
#if defined(__IMXRT1062__) // Teensy 4.x
// *Warning* I disabled the usage of FAST_PINIO as the set/clear operations
// used in the cpp file are not atomic and can effect multiple IO pins
// and if an interrupt happens in between the time the code reads the register
// and writes out the updated value, that changes one or more other IO pins
// on that same IO port, those change will be clobbered when the updated
// values are written back. A fast version can be implemented that uses the
// ports set and clear registers which are atomic.
// typedef volatile uint32_t BusIO_PortReg;
// typedef uint32_t BusIO_PortMask;
// #define BUSIO_USE_FAST_PINIO
#elif defined(__MBED__) || defined(__ZEPHYR__)
// Boards based on RTOS cores like mbed or Zephyr are not going to expose the
// low level registers needed for fast pin manipulation
#undef BUSIO_USE_FAST_PINIO
#elif defined(ARDUINO_ARCH_XMC)
#undef BUSIO_USE_FAST_PINIO
#elif defined(__AVR__) || defined(TEENSYDUINO)
typedef volatile uint8_t BusIO_PortReg;
typedef uint8_t BusIO_PortMask;
#define BUSIO_USE_FAST_PINIO
@ -44,10 +78,12 @@ typedef uint32_t BusIO_PortMask;
#define BUSIO_USE_FAST_PINIO
#elif (defined(__arm__) || defined(ARDUINO_FEATHER52)) && \
!defined(ARDUINO_ARCH_MBED) && !defined(ARDUINO_ARCH_RP2040)
!defined(ARDUINO_ARCH_RP2040) && !defined(ARDUINO_SILABS) && \
!defined(ARDUINO_UNOR4_MINIMA) && !defined(ARDUINO_UNOR4_WIFI) && \
!defined(PORTDUINO)
typedef volatile uint32_t BusIO_PortReg;
typedef uint32_t BusIO_PortMask;
#if not defined(__ASR6501__)
#if !defined(__ASR6501__) && !defined(__ASR6502__)
#define BUSIO_USE_FAST_PINIO
#endif
@ -58,35 +94,49 @@ typedef uint32_t BusIO_PortMask;
/**! The class which defines how we will talk to this device over SPI **/
class Adafruit_SPIDevice {
public:
#ifdef BUSIO_HAS_HW_SPI
Adafruit_SPIDevice(int8_t cspin, uint32_t freq = 1000000,
BitOrder dataOrder = SPI_BITORDER_MSBFIRST,
BusIOBitOrder dataOrder = SPI_BITORDER_MSBFIRST,
uint8_t dataMode = SPI_MODE0, SPIClass *theSPI = &SPI);
#else
Adafruit_SPIDevice(int8_t cspin, uint32_t freq = 1000000,
BusIOBitOrder dataOrder = SPI_BITORDER_MSBFIRST,
uint8_t dataMode = SPI_MODE0, SPIClass *theSPI = nullptr);
#endif
Adafruit_SPIDevice(int8_t cspin, int8_t sck, int8_t miso, int8_t mosi,
uint32_t freq = 1000000,
BitOrder dataOrder = SPI_BITORDER_MSBFIRST,
BusIOBitOrder dataOrder = SPI_BITORDER_MSBFIRST,
uint8_t dataMode = SPI_MODE0);
~Adafruit_SPIDevice();
bool begin(void);
bool read(uint8_t *buffer, size_t len, uint8_t sendvalue = 0xFF);
bool write(uint8_t *buffer, size_t len, uint8_t *prefix_buffer = NULL,
size_t prefix_len = 0);
bool write_then_read(uint8_t *write_buffer, size_t write_len,
bool write(const uint8_t *buffer, size_t len,
const uint8_t *prefix_buffer = nullptr, size_t prefix_len = 0);
bool write_then_read(const uint8_t *write_buffer, size_t write_len,
uint8_t *read_buffer, size_t read_len,
uint8_t sendvalue = 0xFF);
bool write_and_read(uint8_t *buffer, size_t len);
uint8_t transfer(uint8_t send);
void transfer(uint8_t *buffer, size_t len);
void beginTransaction(void);
void endTransaction(void);
void beginTransactionWithAssertingCS();
void endTransactionWithDeassertingCS();
private:
SPIClass *_spi;
SPISettings *_spiSetting;
#ifdef BUSIO_HAS_HW_SPI
SPIClass *_spi = nullptr;
SPISettings *_spiSetting = nullptr;
#else
uint8_t *_spi = nullptr;
uint8_t *_spiSetting = nullptr;
#endif
uint32_t _freq;
BitOrder _dataOrder;
BusIOBitOrder _dataOrder;
uint8_t _dataMode;
void setChipSelect(int value);
int8_t _cs, _sck, _mosi, _miso;
#ifdef BUSIO_USE_FAST_PINIO

11
CMakeLists.txt Normal file
View file

@ -0,0 +1,11 @@
# Adafruit Bus IO Library
# https://github.com/adafruit/Adafruit_BusIO
# MIT License
cmake_minimum_required(VERSION 3.5)
idf_component_register(SRCS "Adafruit_I2CDevice.cpp" "Adafruit_BusIO_Register.cpp" "Adafruit_SPIDevice.cpp" "Adafruit_GenericDevice.cpp"
INCLUDE_DIRS "."
REQUIRES arduino-esp32)
project(Adafruit_BusIO)

View file

@ -1,7 +1,7 @@
# Adafruit Bus IO Library [![Build Status](https://github.com/adafruit/Adafruit_BusIO/workflows/Arduino%20Library%20CI/badge.svg)](https://github.com/adafruit/Adafruit_BusIO/actions)
This is a helper libary to abstract away I2C & SPI transactions and registers
This is a helper library to abstract away I2C, SPI, and 'generic transport' (e.g. UART) transactions and registers
Adafruit invests time and resources providing this open source code, please support Adafruit and open-source hardware by purchasing products from Adafruit!

1
component.mk Normal file
View file

@ -0,0 +1 @@
COMPONENT_ADD_INCLUDEDIRS = .

View file

@ -0,0 +1,219 @@
/*
Advanced example of using bstracted transport for reading and writing
register data from a UART-based device such as a TMC2209
Written with help by Claude!
https://claude.ai/chat/335f50b1-3dd8-435e-9139-57ec7ca26a3c (at this time
chats are not shareable :(
*/
#include "Adafruit_BusIO_Register.h"
#include "Adafruit_GenericDevice.h"
// Debugging macros
#define DEBUG_SERIAL Serial
#ifdef DEBUG_SERIAL
#define DEBUG_PRINT(x) DEBUG_SERIAL.print(x)
#define DEBUG_PRINTLN(x) DEBUG_SERIAL.println(x)
#define DEBUG_PRINT_HEX(x) \
do { \
if (x < 0x10) \
DEBUG_SERIAL.print('0'); \
DEBUG_SERIAL.print(x, HEX); \
DEBUG_SERIAL.print(' '); \
} while (0)
#else
#define DEBUG_PRINT(x)
#define DEBUG_PRINTLN(x)
#define DEBUG_PRINT_HEX(x)
#endif
#define TMC2209_IOIN 0x06
class TMC2209_UART {
private:
Stream *_uart_stream;
uint8_t _addr;
static bool uart_read(void *thiz, uint8_t *buffer, size_t len) {
TMC2209_UART *dev = (TMC2209_UART *)thiz;
uint16_t timeout = 100;
while (dev->_uart_stream->available() < len && timeout--) {
delay(1);
}
if (timeout == 0) {
DEBUG_PRINTLN("Read timeout!");
return false;
}
DEBUG_PRINT("Reading: ");
for (size_t i = 0; i < len; i++) {
buffer[i] = dev->_uart_stream->read();
DEBUG_PRINT_HEX(buffer[i]);
}
DEBUG_PRINTLN("");
return true;
}
static bool uart_write(void *thiz, const uint8_t *buffer, size_t len) {
TMC2209_UART *dev = (TMC2209_UART *)thiz;
DEBUG_PRINT("Writing: ");
for (size_t i = 0; i < len; i++) {
DEBUG_PRINT_HEX(buffer[i]);
}
DEBUG_PRINTLN("");
dev->_uart_stream->write(buffer, len);
return true;
}
static bool uart_readreg(void *thiz, uint8_t *addr_buf, uint8_t addrsiz,
uint8_t *data, uint16_t datalen) {
TMC2209_UART *dev = (TMC2209_UART *)thiz;
while (dev->_uart_stream->available())
dev->_uart_stream->read();
uint8_t packet[4] = {0x05, uint8_t(dev->_addr << 1), addr_buf[0], 0x00};
packet[3] = calcCRC(packet, 3);
if (!uart_write(thiz, packet, 4))
return false;
// Read back echo
uint8_t echo[4];
if (!uart_read(thiz, echo, 4))
return false;
// Verify echo
for (uint8_t i = 0; i < 4; i++) {
if (echo[i] != packet[i]) {
DEBUG_PRINTLN("Echo mismatch");
return false;
}
}
uint8_t response[8]; // sync + 0xFF + reg + 4 data bytes + CRC
if (!uart_read(thiz, response, 8))
return false;
// Verify response
if (response[0] != 0x05) {
DEBUG_PRINTLN("Invalid sync byte");
return false;
}
if (response[1] != 0xFF) {
DEBUG_PRINTLN("Invalid reply address");
return false;
}
if (response[2] != addr_buf[0]) {
DEBUG_PRINTLN("Register mismatch");
return false;
}
uint8_t crc = calcCRC(response, 7);
if (crc != response[7]) {
DEBUG_PRINTLN("CRC mismatch");
return false;
}
memcpy(data, &response[3], 4);
return true;
}
static bool uart_writereg(void *thiz, uint8_t *addr_buf, uint8_t addrsiz,
const uint8_t *data, uint16_t datalen) {
TMC2209_UART *dev = (TMC2209_UART *)thiz;
while (dev->_uart_stream->available())
dev->_uart_stream->read();
uint8_t packet[8] = {0x05,
uint8_t(dev->_addr << 1),
uint8_t(addr_buf[0] | 0x80),
data[0],
data[1],
data[2],
data[3],
0x00};
packet[7] = calcCRC(packet, 7);
if (!uart_write(thiz, packet, 8))
return false;
uint8_t echo[8];
if (!uart_read(thiz, echo, 8))
return false;
for (uint8_t i = 0; i < 8; i++) {
if (echo[i] != packet[i]) {
DEBUG_PRINTLN("Write echo mismatch");
return false;
}
}
return true;
}
static uint8_t calcCRC(uint8_t *data, uint8_t length) {
uint8_t crc = 0;
for (uint8_t i = 0; i < length; i++) {
uint8_t currentByte = data[i];
for (uint8_t j = 0; j < 8; j++) {
if ((crc >> 7) ^ (currentByte & 0x01)) {
crc = (crc << 1) ^ 0x07;
} else {
crc = crc << 1;
}
currentByte = currentByte >> 1;
}
}
return crc;
}
public:
TMC2209_UART(Stream *serial, uint8_t addr)
: _uart_stream(serial), _addr(addr) {}
Adafruit_GenericDevice *createDevice() {
return new Adafruit_GenericDevice(this, uart_read, uart_write, uart_readreg,
uart_writereg);
}
};
void setup() {
Serial.begin(115200);
while (!Serial)
;
delay(100);
Serial.println("TMC2209 Generic Device register read/write test!");
Serial1.begin(115200);
TMC2209_UART uart(&Serial1, 0);
Adafruit_GenericDevice *device = uart.createDevice();
device->begin();
// Create register object for IOIN
Adafruit_BusIO_Register ioin_reg(device,
TMC2209_IOIN, // device and register address
4, // width = 4 bytes
MSBFIRST, // byte order
1); // address width = 1 byte
Serial.print("IOIN = 0x");
Serial.println(ioin_reg.read(), HEX);
// Create RegisterBits for VERSION field (bits 31:24)
Adafruit_BusIO_RegisterBits version_bits(
&ioin_reg, 8, 24); // 8 bits wide, starting at bit 24
Serial.println("Reading VERSION...");
uint8_t version = version_bits.read();
Serial.print("VERSION = 0x");
Serial.println(version, HEX);
}
void loop() { delay(1000); }

View file

@ -0,0 +1,98 @@
/*
Abstracted transport for reading and writing data from a UART-based
device such as a TMC2209
Written with help by Claude!
https://claude.ai/chat/335f50b1-3dd8-435e-9139-57ec7ca26a3c (at this time
chats are not shareable :(
*/
#include "Adafruit_GenericDevice.h"
/**
* Basic UART device class that demonstrates using GenericDevice with a Stream
* interface. This example shows how to wrap a Stream (like HardwareSerial or
* SoftwareSerial) with read/write callbacks that can be used by BusIO's
* register functions.
*/
class UARTDevice {
public:
UARTDevice(Stream *serial) : _serial(serial) {}
// Static callback for writing data to UART
// Called by GenericDevice when data needs to be sent
static bool uart_write(void *thiz, const uint8_t *buffer, size_t len) {
UARTDevice *dev = (UARTDevice *)thiz;
dev->_serial->write(buffer, len);
return true;
}
// Static callback for reading data from UART
// Includes timeout and will return false if not enough data available
static bool uart_read(void *thiz, uint8_t *buffer, size_t len) {
UARTDevice *dev = (UARTDevice *)thiz;
uint16_t timeout = 100;
while (dev->_serial->available() < len && timeout--) {
delay(1);
}
if (timeout == 0) {
return false;
}
for (size_t i = 0; i < len; i++) {
buffer[i] = dev->_serial->read();
}
return true;
}
// Create a GenericDevice instance using our callbacks
Adafruit_GenericDevice *createDevice() {
return new Adafruit_GenericDevice(this, uart_read, uart_write);
}
private:
Stream *_serial; // Underlying Stream instance (HardwareSerial, etc)
};
void setup() {
Serial.begin(115200);
while (!Serial)
;
delay(100);
Serial.println("Generic Device test!");
// Initialize UART for device communication
Serial1.begin(115200);
// Create UART wrapper and BusIO device
UARTDevice uart(&Serial1);
Adafruit_GenericDevice *device = uart.createDevice();
device->begin();
// Test write/read cycle
uint8_t write_buf[4] = {0x5, 0x0, 0x0, 0x48};
uint8_t read_buf[8];
Serial.println("Writing data...");
if (!device->write(write_buf, 4)) {
Serial.println("Write failed!");
return;
}
Serial.println("Reading response...");
if (!device->read(read_buf, 8)) {
Serial.println("Read failed!");
return;
}
// Print response bytes
Serial.print("Got response: ");
for (int i = 0; i < 8; i++) {
Serial.print("0x");
Serial.print(read_buf[i], HEX);
Serial.print(" ");
}
Serial.println();
}
void loop() { delay(1000); }

View file

@ -3,19 +3,20 @@
Adafruit_I2CDevice i2c_dev = Adafruit_I2CDevice(0x10);
void setup() {
while (!Serial) { delay(10); }
while (!Serial) {
delay(10);
}
Serial.begin(115200);
Serial.println("I2C address detection test");
if (!i2c_dev.begin()) {
Serial.print("Did not find device at 0x");
Serial.println(i2c_dev.address(), HEX);
while (1);
while (1)
;
}
Serial.print("Device found on address 0x");
Serial.println(i2c_dev.address(), HEX);
}
void loop() {
}
void loop() {}

View file

@ -3,16 +3,18 @@
#define I2C_ADDRESS 0x60
Adafruit_I2CDevice i2c_dev = Adafruit_I2CDevice(I2C_ADDRESS);
void setup() {
while (!Serial) { delay(10); }
while (!Serial) {
delay(10);
}
Serial.begin(115200);
Serial.println("I2C device read and write test");
if (!i2c_dev.begin()) {
Serial.print("Did not find device at 0x");
Serial.println(i2c_dev.address(), HEX);
while (1);
while (1)
;
}
Serial.print("Device found on address 0x");
Serial.println(i2c_dev.address(), HEX);
@ -21,21 +23,23 @@ void setup() {
// Try to read 32 bytes
i2c_dev.read(buffer, 32);
Serial.print("Read: ");
for (uint8_t i=0; i<32; i++) {
Serial.print("0x"); Serial.print(buffer[i], HEX); Serial.print(", ");
for (uint8_t i = 0; i < 32; i++) {
Serial.print("0x");
Serial.print(buffer[i], HEX);
Serial.print(", ");
}
Serial.println();
// read a register by writing first, then reading
buffer[0] = 0x0C; // we'll reuse the same buffer
buffer[0] = 0x0C; // we'll reuse the same buffer
i2c_dev.write_then_read(buffer, 1, buffer, 2, false);
Serial.print("Write then Read: ");
for (uint8_t i=0; i<2; i++) {
Serial.print("0x"); Serial.print(buffer[i], HEX); Serial.print(", ");
for (uint8_t i = 0; i < 2; i++) {
Serial.print("0x");
Serial.print(buffer[i], HEX);
Serial.print(", ");
}
Serial.println();
}
void loop() {
}
void loop() {}

View file

@ -1,38 +1,43 @@
#include <Adafruit_I2CDevice.h>
#include <Adafruit_BusIO_Register.h>
#include <Adafruit_I2CDevice.h>
#define I2C_ADDRESS 0x60
Adafruit_I2CDevice i2c_dev = Adafruit_I2CDevice(I2C_ADDRESS);
void setup() {
while (!Serial) { delay(10); }
while (!Serial) {
delay(10);
}
Serial.begin(115200);
Serial.println("I2C device register test");
if (!i2c_dev.begin()) {
Serial.print("Did not find device at 0x");
Serial.println(i2c_dev.address(), HEX);
while (1);
while (1)
;
}
Serial.print("Device found on address 0x");
Serial.println(i2c_dev.address(), HEX);
Adafruit_BusIO_Register id_reg = Adafruit_BusIO_Register(&i2c_dev, 0x0C, 2, LSBFIRST);
Adafruit_BusIO_Register id_reg =
Adafruit_BusIO_Register(&i2c_dev, 0x0C, 2, LSBFIRST);
uint16_t id;
id_reg.read(&id);
Serial.print("ID register = 0x"); Serial.println(id, HEX);
Serial.print("ID register = 0x");
Serial.println(id, HEX);
Adafruit_BusIO_Register thresh_reg = Adafruit_BusIO_Register(&i2c_dev, 0x01, 2, LSBFIRST);
Adafruit_BusIO_Register thresh_reg =
Adafruit_BusIO_Register(&i2c_dev, 0x01, 2, LSBFIRST);
uint16_t thresh;
thresh_reg.read(&thresh);
Serial.print("Initial threshold register = 0x"); Serial.println(thresh, HEX);
Serial.print("Initial threshold register = 0x");
Serial.println(thresh, HEX);
thresh_reg.write(~thresh);
Serial.print("Post threshold register = 0x"); Serial.println(thresh_reg.read(), HEX);
Serial.print("Post threshold register = 0x");
Serial.println(thresh_reg.read(), HEX);
}
void loop() {
}
void loop() {}

View file

@ -9,7 +9,9 @@ Adafruit_SPIDevice *spi_dev = NULL; // new Adafruit_SPIDevice(SPIDEVICE_CS);
Adafruit_I2CDevice *i2c_dev = new Adafruit_I2CDevice(I2C_ADDRESS);
void setup() {
while (!Serial) { delay(10); }
while (!Serial) {
delay(10);
}
Serial.begin(115200);
Serial.println("I2C or SPI device register test");
@ -27,12 +29,12 @@ void setup() {
}
}
Adafruit_BusIO_Register id_reg = Adafruit_BusIO_Register(i2c_dev, spi_dev, ADDRBIT8_HIGH_TOREAD, 0x0F);
uint8_t id;
Adafruit_BusIO_Register id_reg =
Adafruit_BusIO_Register(i2c_dev, spi_dev, ADDRBIT8_HIGH_TOREAD, 0x0F);
uint8_t id = 0;
id_reg.read(&id);
Serial.print("ID register = 0x"); Serial.println(id, HEX);
Serial.print("ID register = 0x");
Serial.println(id, HEX);
}
void loop() {
}
void loop() {}

View file

@ -1,28 +1,34 @@
#include <Adafruit_SPIDevice.h>
#define SPIDEVICE_CS 10
Adafruit_SPIDevice spi_dev = Adafruit_SPIDevice(SPIDEVICE_CS, 100000, SPI_BITORDER_MSBFIRST, SPI_MODE1);
//Adafruit_SPIDevice spi_dev = Adafruit_SPIDevice(SPIDEVICE_CS, 13, 12, 11, 100000, SPI_BITORDER_MSBFIRST, SPI_MODE1);
Adafruit_SPIDevice spi_dev =
Adafruit_SPIDevice(SPIDEVICE_CS, 100000, SPI_BITORDER_MSBFIRST, SPI_MODE1);
// Adafruit_SPIDevice spi_dev = Adafruit_SPIDevice(SPIDEVICE_CS, 13, 12, 11,
// 100000, SPI_BITORDER_MSBFIRST, SPI_MODE1);
void setup() {
while (!Serial) { delay(10); }
while (!Serial) {
delay(10);
}
Serial.begin(115200);
Serial.println("SPI device mode test");
if (!spi_dev.begin()) {
Serial.println("Could not initialize SPI device");
while (1);
while (1)
;
}
}
void loop() {
Serial.println("\n\nTransfer test");
for (uint16_t x=0; x<=0xFF; x++) {
uint8_t i = x;
Serial.print("0x"); Serial.print(i, HEX);
for (uint16_t x = 0; x <= 0xFF; x++) {
uint8_t i = x;
Serial.print("0x");
Serial.print(i, HEX);
spi_dev.read(&i, 1, i);
Serial.print("/"); Serial.print(i, HEX);
Serial.print("/");
Serial.print(i, HEX);
Serial.print(", ");
delay(25);
}

View file

@ -3,15 +3,17 @@
#define SPIDEVICE_CS 10
Adafruit_SPIDevice spi_dev = Adafruit_SPIDevice(SPIDEVICE_CS);
void setup() {
while (!Serial) { delay(10); }
while (!Serial) {
delay(10);
}
Serial.begin(115200);
Serial.println("SPI device read and write test");
if (!spi_dev.begin()) {
Serial.println("Could not initialize SPI device");
while (1);
while (1)
;
}
uint8_t buffer[32];
@ -19,21 +21,23 @@ void setup() {
// Try to read 32 bytes
spi_dev.read(buffer, 32);
Serial.print("Read: ");
for (uint8_t i=0; i<32; i++) {
Serial.print("0x"); Serial.print(buffer[i], HEX); Serial.print(", ");
for (uint8_t i = 0; i < 32; i++) {
Serial.print("0x");
Serial.print(buffer[i], HEX);
Serial.print(", ");
}
Serial.println();
// read a register by writing first, then reading
buffer[0] = 0x8F; // we'll reuse the same buffer
buffer[0] = 0x8F; // we'll reuse the same buffer
spi_dev.write_then_read(buffer, 1, buffer, 2, false);
Serial.print("Write then Read: ");
for (uint8_t i=0; i<2; i++) {
Serial.print("0x"); Serial.print(buffer[i], HEX); Serial.print(", ");
for (uint8_t i = 0; i < 2; i++) {
Serial.print("0x");
Serial.print(buffer[i], HEX);
Serial.print(", ");
}
Serial.println();
}
void loop() {
}
void loop() {}

View file

@ -1,163 +1,233 @@
/***************************************************
/***************************************************
This is an example for how to use Adafruit_BusIO_RegisterBits from Adafruit_BusIO library.
This is an example for how to use Adafruit_BusIO_RegisterBits from
Adafruit_BusIO library.
Designed specifically to work with the Adafruit RTD Sensor
----> https://www.adafruit.com/products/3328
uisng a MAX31865 RTD-to-Digital Converter
----> https://datasheets.maximintegrated.com/en/ds/MAX31865.pdf
This sensor uses SPI to communicate, 4 pins are required to
This sensor uses SPI to communicate, 4 pins are required to
interface.
A fifth pin helps to detect when a new conversion is ready.
Adafruit invests time and resources providing this open source code,
please support Adafruit and open-source hardware by purchasing
Adafruit invests time and resources providing this open source code,
please support Adafruit and open-source hardware by purchasing
products from Adafruit!
Example written (2020/3) by Andreas Hardtung/AnHard.
Example written (2020/3) by Andreas Hardtung/AnHard.
BSD license, all text above must be included in any redistribution
****************************************************/
#include <Adafruit_BusIO_Register.h>
#include <Adafruit_SPIDevice.h>
#define MAX31865_SPI_SPEED (5000000)
#define MAX31865_SPI_SPEED (5000000)
#define MAX31865_SPI_BITORDER (SPI_BITORDER_MSBFIRST)
#define MAX31865_SPI_MODE (SPI_MODE1)
#define MAX31865_SPI_MODE (SPI_MODE1)
#define MAX31865_SPI_CS (10)
#define MAX31865_READY_PIN (2)
#define MAX31865_SPI_CS (10)
#define MAX31865_READY_PIN (2)
Adafruit_SPIDevice spi_dev = Adafruit_SPIDevice(
MAX31865_SPI_CS, MAX31865_SPI_SPEED, MAX31865_SPI_BITORDER,
MAX31865_SPI_MODE, &SPI); // Hardware SPI
// Adafruit_SPIDevice spi_dev = Adafruit_SPIDevice( MAX31865_SPI_CS, 13, 12, 11,
// MAX31865_SPI_SPEED, MAX31865_SPI_BITORDER, MAX31865_SPI_MODE); // Software
// SPI
Adafruit_SPIDevice spi_dev = Adafruit_SPIDevice( MAX31865_SPI_CS, MAX31865_SPI_SPEED, MAX31865_SPI_BITORDER, MAX31865_SPI_MODE, &SPI); // Hardware SPI
// Adafruit_SPIDevice spi_dev = Adafruit_SPIDevice( MAX31865_SPI_CS, 13, 12, 11, MAX31865_SPI_SPEED, MAX31865_SPI_BITORDER, MAX31865_SPI_MODE); // Software SPI
// MAX31865 chip related
// *********************************************************************************************
Adafruit_BusIO_Register config_reg =
Adafruit_BusIO_Register(&spi_dev, 0x00, ADDRBIT8_HIGH_TOWRITE, 1, MSBFIRST);
Adafruit_BusIO_RegisterBits bias_bit =
Adafruit_BusIO_RegisterBits(&config_reg, 1, 7);
Adafruit_BusIO_RegisterBits auto_bit =
Adafruit_BusIO_RegisterBits(&config_reg, 1, 6);
Adafruit_BusIO_RegisterBits oneS_bit =
Adafruit_BusIO_RegisterBits(&config_reg, 1, 5);
Adafruit_BusIO_RegisterBits wire_bit =
Adafruit_BusIO_RegisterBits(&config_reg, 1, 4);
Adafruit_BusIO_RegisterBits faultT_bits =
Adafruit_BusIO_RegisterBits(&config_reg, 2, 2);
Adafruit_BusIO_RegisterBits faultR_bit =
Adafruit_BusIO_RegisterBits(&config_reg, 1, 1);
Adafruit_BusIO_RegisterBits fi50hz_bit =
Adafruit_BusIO_RegisterBits(&config_reg, 1, 0);
// MAX31865 chip related *********************************************************************************************
Adafruit_BusIO_Register config_reg = Adafruit_BusIO_Register(&spi_dev, 0x00, ADDRBIT8_HIGH_TOWRITE, 1, MSBFIRST);
Adafruit_BusIO_RegisterBits bias_bit = Adafruit_BusIO_RegisterBits(&config_reg, 1, 7);
Adafruit_BusIO_RegisterBits auto_bit = Adafruit_BusIO_RegisterBits(&config_reg, 1, 6);
Adafruit_BusIO_RegisterBits oneS_bit = Adafruit_BusIO_RegisterBits(&config_reg, 1, 5);
Adafruit_BusIO_RegisterBits wire_bit = Adafruit_BusIO_RegisterBits(&config_reg, 1, 4);
Adafruit_BusIO_RegisterBits faultT_bits = Adafruit_BusIO_RegisterBits(&config_reg, 2, 2);
Adafruit_BusIO_RegisterBits faultR_bit = Adafruit_BusIO_RegisterBits(&config_reg, 1, 1);
Adafruit_BusIO_RegisterBits fi50hz_bit = Adafruit_BusIO_RegisterBits(&config_reg, 1, 0);
Adafruit_BusIO_Register rRatio_reg =
Adafruit_BusIO_Register(&spi_dev, 0x01, ADDRBIT8_HIGH_TOWRITE, 2, MSBFIRST);
Adafruit_BusIO_RegisterBits rRatio_bits =
Adafruit_BusIO_RegisterBits(&rRatio_reg, 15, 1);
Adafruit_BusIO_RegisterBits fault_bit =
Adafruit_BusIO_RegisterBits(&rRatio_reg, 1, 0);
Adafruit_BusIO_Register rRatio_reg = Adafruit_BusIO_Register(&spi_dev, 0x01, ADDRBIT8_HIGH_TOWRITE, 2, MSBFIRST);
Adafruit_BusIO_RegisterBits rRatio_bits = Adafruit_BusIO_RegisterBits(&rRatio_reg, 15, 1);
Adafruit_BusIO_RegisterBits fault_bit = Adafruit_BusIO_RegisterBits(&rRatio_reg, 1, 0);
Adafruit_BusIO_Register maxRratio_reg =
Adafruit_BusIO_Register(&spi_dev, 0x03, ADDRBIT8_HIGH_TOWRITE, 2, MSBFIRST);
Adafruit_BusIO_RegisterBits maxRratio_bits =
Adafruit_BusIO_RegisterBits(&maxRratio_reg, 15, 1);
Adafruit_BusIO_Register maxRratio_reg = Adafruit_BusIO_Register(&spi_dev, 0x03, ADDRBIT8_HIGH_TOWRITE, 2, MSBFIRST);
Adafruit_BusIO_RegisterBits maxRratio_bits = Adafruit_BusIO_RegisterBits(&maxRratio_reg, 15, 1);
Adafruit_BusIO_Register minRratio_reg =
Adafruit_BusIO_Register(&spi_dev, 0x05, ADDRBIT8_HIGH_TOWRITE, 2, MSBFIRST);
Adafruit_BusIO_RegisterBits minRratio_bits =
Adafruit_BusIO_RegisterBits(&minRratio_reg, 15, 1);
Adafruit_BusIO_Register minRratio_reg = Adafruit_BusIO_Register(&spi_dev, 0x05, ADDRBIT8_HIGH_TOWRITE, 2, MSBFIRST);
Adafruit_BusIO_RegisterBits minRratio_bits = Adafruit_BusIO_RegisterBits(&minRratio_reg, 15, 1);
Adafruit_BusIO_Register fault_reg = Adafruit_BusIO_Register(&spi_dev, 0x07, ADDRBIT8_HIGH_TOWRITE, 1, MSBFIRST);
Adafruit_BusIO_RegisterBits range_high_fault_bit = Adafruit_BusIO_RegisterBits(&fault_reg, 1, 7);
Adafruit_BusIO_RegisterBits range_low_fault_bit = Adafruit_BusIO_RegisterBits(&fault_reg, 1, 6);
Adafruit_BusIO_RegisterBits refin_high_fault_bit = Adafruit_BusIO_RegisterBits(&fault_reg, 1, 5);
Adafruit_BusIO_RegisterBits refin_low_fault_bit = Adafruit_BusIO_RegisterBits(&fault_reg, 1, 4);
Adafruit_BusIO_RegisterBits rtdin_low_fault_bit = Adafruit_BusIO_RegisterBits(&fault_reg, 1, 3);
Adafruit_BusIO_RegisterBits voltage_fault_bit = Adafruit_BusIO_RegisterBits(&fault_reg, 1, 2);
Adafruit_BusIO_Register fault_reg =
Adafruit_BusIO_Register(&spi_dev, 0x07, ADDRBIT8_HIGH_TOWRITE, 1, MSBFIRST);
Adafruit_BusIO_RegisterBits range_high_fault_bit =
Adafruit_BusIO_RegisterBits(&fault_reg, 1, 7);
Adafruit_BusIO_RegisterBits range_low_fault_bit =
Adafruit_BusIO_RegisterBits(&fault_reg, 1, 6);
Adafruit_BusIO_RegisterBits refin_high_fault_bit =
Adafruit_BusIO_RegisterBits(&fault_reg, 1, 5);
Adafruit_BusIO_RegisterBits refin_low_fault_bit =
Adafruit_BusIO_RegisterBits(&fault_reg, 1, 4);
Adafruit_BusIO_RegisterBits rtdin_low_fault_bit =
Adafruit_BusIO_RegisterBits(&fault_reg, 1, 3);
Adafruit_BusIO_RegisterBits voltage_fault_bit =
Adafruit_BusIO_RegisterBits(&fault_reg, 1, 2);
// Print the details of the configuration register.
void printConfig( void ) {
Serial.print("BIAS: "); if (bias_bit.read() ) Serial.print("ON"); else Serial.print("OFF");
Serial.print(", AUTO: "); if (auto_bit.read() ) Serial.print("ON"); else Serial.print("OFF");
Serial.print(", ONES: "); if (oneS_bit.read() ) Serial.print("ON"); else Serial.print("OFF");
Serial.print(", WIRE: "); if (wire_bit.read() ) Serial.print("3"); else Serial.print("2/4");
Serial.print(", FAULTCLEAR: "); if (faultR_bit.read() ) Serial.print("ON"); else Serial.print("OFF");
Serial.print(", "); if (fi50hz_bit.read() ) Serial.print("50HZ"); else Serial.print("60HZ");
void printConfig(void) {
Serial.print("BIAS: ");
if (bias_bit.read())
Serial.print("ON");
else
Serial.print("OFF");
Serial.print(", AUTO: ");
if (auto_bit.read())
Serial.print("ON");
else
Serial.print("OFF");
Serial.print(", ONES: ");
if (oneS_bit.read())
Serial.print("ON");
else
Serial.print("OFF");
Serial.print(", WIRE: ");
if (wire_bit.read())
Serial.print("3");
else
Serial.print("2/4");
Serial.print(", FAULTCLEAR: ");
if (faultR_bit.read())
Serial.print("ON");
else
Serial.print("OFF");
Serial.print(", ");
if (fi50hz_bit.read())
Serial.print("50HZ");
else
Serial.print("60HZ");
Serial.println();
}
// Check and print faults. Then clear them.
void checkFaults( void ) {
void checkFaults(void) {
if (fault_bit.read()) {
Serial.print("MAX: "); Serial.println(maxRratio_bits.read());
Serial.print("VAL: "); Serial.println( rRatio_bits.read());
Serial.print("MIN: "); Serial.println(minRratio_bits.read());
Serial.print("MAX: ");
Serial.println(maxRratio_bits.read());
Serial.print("VAL: ");
Serial.println(rRatio_bits.read());
Serial.print("MIN: ");
Serial.println(minRratio_bits.read());
if (range_high_fault_bit.read() ) Serial.println("Range high fault");
if ( range_low_fault_bit.read() ) Serial.println("Range low fault");
if (refin_high_fault_bit.read() ) Serial.println("REFIN high fault");
if ( refin_low_fault_bit.read() ) Serial.println("REFIN low fault");
if ( rtdin_low_fault_bit.read() ) Serial.println("RTDIN low fault");
if ( voltage_fault_bit.read() ) Serial.println("Voltage fault");
if (range_high_fault_bit.read())
Serial.println("Range high fault");
if (range_low_fault_bit.read())
Serial.println("Range low fault");
if (refin_high_fault_bit.read())
Serial.println("REFIN high fault");
if (refin_low_fault_bit.read())
Serial.println("REFIN low fault");
if (rtdin_low_fault_bit.read())
Serial.println("RTDIN low fault");
if (voltage_fault_bit.read())
Serial.println("Voltage fault");
faultR_bit.write(1); // clear fault
}
}
void setup() {
#if (MAX31865_1_READY_PIN != -1)
pinMode(MAX31865_READY_PIN ,INPUT_PULLUP);
#endif
#if (MAX31865_1_READY_PIN != -1)
pinMode(MAX31865_READY_PIN, INPUT_PULLUP);
#endif
while (!Serial) { delay(10); }
while (!Serial) {
delay(10);
}
Serial.begin(115200);
Serial.println("SPI Adafruit_BusIO_RegisterBits test on MAX31865");
if (!spi_dev.begin()) {
Serial.println("Could not initialize SPI device");
while (1);
while (1)
;
}
// Set up for automode 50Hz. We don't care about selfheating. We want the highest possible sampling rate.
// Set up for automode 50Hz. We don't care about selfheating. We want the
// highest possible sampling rate.
auto_bit.write(0); // Don't switch filtermode while auto_mode is on.
fi50hz_bit.write(1); // Set filter to 50Hz mode.
faultR_bit.write(1); // Clear faults.
bias_bit.write(1); // In automode we want to have the bias current always on.
delay(5); // Wait until bias current settles down.
// 10.5 time constants of the input RC network is required.
// 10ms worst case for 10kω reference resistor and a 0.1µF capacitor across the RTD inputs.
// Adafruit Module has 0.1µF and only 430/4300ω So here 0.43/4.3ms
auto_bit.write(1); // Now we can set automode. Automatically starting first conversion.
bias_bit.write(1); // In automode we want to have the bias current always on.
delay(5); // Wait until bias current settles down.
// 10.5 time constants of the input RC network is required.
// 10ms worst case for 10kω reference resistor and a 0.1µF capacitor
// across the RTD inputs. Adafruit Module has 0.1µF and only
// 430/4300ω So here 0.43/4.3ms
auto_bit.write(
1); // Now we can set automode. Automatically starting first conversion.
// Test the READY_PIN
#if (defined( MAX31865_READY_PIN ) && (MAX31865_READY_PIN != -1))
int i = 0;
while (digitalRead(MAX31865_READY_PIN) && i++ <= 100) { delay(1); }
if (i >= 100) {
Serial.print("ERROR: Max31865 Pin detection does not work. PIN:");
Serial.println(MAX31865_READY_PIN);
}
#else
delay(100);
#endif
// Test the READY_PIN
#if (defined(MAX31865_READY_PIN) && (MAX31865_READY_PIN != -1))
int i = 0;
while (digitalRead(MAX31865_READY_PIN) && i++ <= 100) {
delay(1);
}
if (i >= 100) {
Serial.print("ERROR: Max31865 Pin detection does not work. PIN:");
Serial.println(MAX31865_READY_PIN);
}
#else
delay(100);
#endif
// Set ratio range.
// Setting the temperatures would need some more calculation - not related to Adafruit_BusIO_RegisterBits.
// Setting the temperatures would need some more calculation - not related to
// Adafruit_BusIO_RegisterBits.
uint16_t ratio = rRatio_bits.read();
maxRratio_bits.write( (ratio < 0x8fffu-1000u) ? ratio + 1000u : 0x8fffu );
minRratio_bits.write( (ratio > 1000u) ? ratio - 1000u : 0u );
maxRratio_bits.write((ratio < 0x8fffu - 1000u) ? ratio + 1000u : 0x8fffu);
minRratio_bits.write((ratio > 1000u) ? ratio - 1000u : 0u);
printConfig();
checkFaults();
}
void loop() {
#if (defined( MAX31865_READY_PIN ) && (MAX31865_1_READY_PIN != -1))
// Is converstion ready?
if (!digitalRead(MAX31865_READY_PIN))
#else
// Warant conversion is ready.
delay(21); // 21ms for 50Hz-mode. 19ms in 60Hz-mode.
#endif
{
// Read ratio, calculate temperature, scale, filter and print.
Serial.println( rRatio2C( rRatio_bits.read() ) * 100.0f, 0); // Temperature scaled by 100
// Check, print, clear faults.
checkFaults();
}
#if (defined(MAX31865_READY_PIN) && (MAX31865_1_READY_PIN != -1))
// Is conversion ready?
if (!digitalRead(MAX31865_READY_PIN))
#else
// Warant conversion is ready.
delay(21); // 21ms for 50Hz-mode. 19ms in 60Hz-mode.
#endif
{
// Read ratio, calculate temperature, scale, filter and print.
Serial.println(rRatio2C(rRatio_bits.read()) * 100.0f,
0); // Temperature scaled by 100
// Check, print, clear faults.
checkFaults();
}
// Do something else.
//delay(15000);
// delay(15000);
}
// Module/Sensor related. Here Adafruit PT100 module with a 2_Wire PT100 Class C *****************************
// Module/Sensor related. Here Adafruit PT100 module with a 2_Wire PT100 Class C
// *****************************
float rRatio2C(uint16_t ratio) {
// A simple linear conversion.
const float R0 = 100.0f;
@ -165,28 +235,34 @@ float rRatio2C(uint16_t ratio) {
const float alphaPT = 0.003850f;
const float ADCmax = (1u << 15) - 1.0f;
const float rscale = Rref / ADCmax;
// Measured temperature in boiling water 101.08°C with factor a = 1 and b = 0. Rref and MAX at about 22±2°C.
// Measured temperature in ice/water bath 0.76°C with factor a = 1 and b = 0. Rref and MAX at about 22±2°C.
//const float a = 1.0f / (alphaPT * R0);
const float a = (100.0f/101.08f) / (alphaPT * R0);
//const float b = 0.0f; // 101.08
const float b = -0.76f; // 100.32 > 101.08
// Measured temperature in boiling water 101.08°C with factor a = 1 and b = 0.
// Rref and MAX at about 22±2°C. Measured temperature in ice/water bath 0.76°C
// with factor a = 1 and b = 0. Rref and MAX at about 22±2°C.
// const float a = 1.0f / (alphaPT * R0);
const float a = (100.0f / 101.08f) / (alphaPT * R0);
// const float b = 0.0f; // 101.08
const float b = -0.76f; // 100.32 > 101.08
return filterRing( ((ratio * rscale) - R0) * a + b );
return filterRing(((ratio * rscale) - R0) * a + b);
}
// General purpose *********************************************************************************************
// General purpose
// *********************************************************************************************
#define RINGLENGTH 250
float filterRing( float newVal ) {
static float ring[RINGLENGTH] = { 0.0 };
float filterRing(float newVal) {
static float ring[RINGLENGTH] = {0.0};
static uint8_t ringIndex = 0;
static bool ringFull = false;
if ( ringIndex == RINGLENGTH ) { ringFull = true; ringIndex = 0; }
if (ringIndex == RINGLENGTH) {
ringFull = true;
ringIndex = 0;
}
ring[ringIndex] = newVal;
uint8_t loopEnd = (ringFull) ? RINGLENGTH : ringIndex + 1;
float ringSum = 0.0f;
for (uint8_t i = 0; i < loopEnd; i++) ringSum += ring[i];
for (uint8_t i = 0; i < loopEnd; i++)
ringSum += ring[i];
ringIndex++;
return ringSum / loopEnd;
}

View file

@ -5,30 +5,36 @@
Adafruit_SPIDevice spi_dev = Adafruit_SPIDevice(SPIDEVICE_CS);
void setup() {
while (!Serial) { delay(10); }
while (!Serial) {
delay(10);
}
Serial.begin(115200);
Serial.println("SPI device register test");
if (!spi_dev.begin()) {
Serial.println("Could not initialize SPI device");
while (1);
while (1)
;
}
Adafruit_BusIO_Register id_reg = Adafruit_BusIO_Register(&spi_dev, 0x0F, ADDRBIT8_HIGH_TOREAD);
uint8_t id;
Adafruit_BusIO_Register id_reg =
Adafruit_BusIO_Register(&spi_dev, 0x0F, ADDRBIT8_HIGH_TOREAD);
uint8_t id = 0;
id_reg.read(&id);
Serial.print("ID register = 0x"); Serial.println(id, HEX);
Serial.print("ID register = 0x");
Serial.println(id, HEX);
Adafruit_BusIO_Register thresh_reg = Adafruit_BusIO_Register(&spi_dev, 0x0C, ADDRBIT8_HIGH_TOREAD, 2, LSBFIRST);
uint16_t thresh;
Adafruit_BusIO_Register thresh_reg = Adafruit_BusIO_Register(
&spi_dev, 0x0C, ADDRBIT8_HIGH_TOREAD, 2, LSBFIRST);
uint16_t thresh = 0;
thresh_reg.read(&thresh);
Serial.print("Initial threshold register = 0x"); Serial.println(thresh, HEX);
Serial.print("Initial threshold register = 0x");
Serial.println(thresh, HEX);
thresh_reg.write(~thresh);
Serial.print("Post threshold register = 0x"); Serial.println(thresh_reg.read(), HEX);
Serial.print("Post threshold register = 0x");
Serial.println(thresh_reg.read(), HEX);
}
void loop() {
}
void loop() {}

View file

@ -1,5 +1,5 @@
name=Adafruit BusIO
version=1.7.5
version=1.17.2
author=Adafruit
maintainer=Adafruit <info@adafruit.com>
sentence=This is a library for abstracting away UART, I2C and SPI interfacing