Skip to content

Commit cc66c42

Browse files
authored
Merge pull request #137 from adafruit/genericdevice
add generic device for non-standard transports
2 parents 55e4f83 + 1a7e578 commit cc66c42

File tree

10 files changed

+491
-16
lines changed

10 files changed

+491
-16
lines changed

Adafruit_BusIO_Register.cpp

Lines changed: 31 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -88,6 +88,26 @@ Adafruit_BusIO_Register::Adafruit_BusIO_Register(
8888
_width = width;
8989
}
9090

91+
/*!
92+
* @brief Create a register we access over a GenericDevice
93+
* @param genericdevice Generic device to use
94+
* @param reg_addr Register address we will read/write
95+
* @param width Width of the register in bytes (1-4)
96+
* @param byteorder Byte order of register data (LSBFIRST or MSBFIRST)
97+
* @param address_width Width of the register address in bytes (1 or 2)
98+
*/
99+
Adafruit_BusIO_Register::Adafruit_BusIO_Register(
100+
Adafruit_GenericDevice *genericdevice, uint16_t reg_addr, uint8_t width,
101+
uint8_t byteorder, uint8_t address_width) {
102+
_i2cdevice = nullptr;
103+
_spidevice = nullptr;
104+
_genericdevice = genericdevice;
105+
_addrwidth = address_width;
106+
_address = reg_addr;
107+
_byteorder = byteorder;
108+
_width = width;
109+
}
110+
91111
/*!
92112
* @brief Write a buffer of data to the register location
93113
* @param buffer Pointer to data to write
@@ -96,17 +116,14 @@ Adafruit_BusIO_Register::Adafruit_BusIO_Register(
96116
* uncheckable)
97117
*/
98118
bool Adafruit_BusIO_Register::write(uint8_t *buffer, uint8_t len) {
99-
100119
uint8_t addrbuffer[2] = {(uint8_t)(_address & 0xFF),
101120
(uint8_t)(_address >> 8)};
102-
103121
if (_i2cdevice) {
104122
return _i2cdevice->write(buffer, len, true, addrbuffer, _addrwidth);
105123
}
106124
if (_spidevice) {
107125
if (_spiregtype == ADDRESSED_OPCODE_BIT0_LOW_TO_WRITE) {
108126
// very special case!
109-
110127
// pass the special opcode address which we set as the high byte of the
111128
// regaddr
112129
addrbuffer[0] =
@@ -116,7 +133,6 @@ bool Adafruit_BusIO_Register::write(uint8_t *buffer, uint8_t len) {
116133
// the address appears to be a byte longer
117134
return _spidevice->write(buffer, len, addrbuffer, _addrwidth + 1);
118135
}
119-
120136
if (_spiregtype == ADDRBIT8_HIGH_TOREAD) {
121137
addrbuffer[0] &= ~0x80;
122138
}
@@ -129,6 +145,9 @@ bool Adafruit_BusIO_Register::write(uint8_t *buffer, uint8_t len) {
129145
}
130146
return _spidevice->write(buffer, len, addrbuffer, _addrwidth);
131147
}
148+
if (_genericdevice) {
149+
return _genericdevice->writeRegister(addrbuffer, _addrwidth, buffer, len);
150+
}
132151
return false;
133152
}
134153

@@ -192,23 +211,20 @@ uint32_t Adafruit_BusIO_Register::read(void) {
192211
uint32_t Adafruit_BusIO_Register::readCached(void) { return _cached; }
193212

194213
/*!
195-
* @brief Read a buffer of data from the register location
196-
* @param buffer Pointer to data to read into
197-
* @param len Number of bytes to read
198-
* @return True on successful write (only really useful for I2C as SPI is
199-
* uncheckable)
200-
*/
214+
@brief Read a number of bytes from a register into a buffer
215+
@param buffer Buffer to read data into
216+
@param len Number of bytes to read into the buffer
217+
@return true on successful read, otherwise false
218+
*/
201219
bool Adafruit_BusIO_Register::read(uint8_t *buffer, uint8_t len) {
202220
uint8_t addrbuffer[2] = {(uint8_t)(_address & 0xFF),
203221
(uint8_t)(_address >> 8)};
204-
205222
if (_i2cdevice) {
206223
return _i2cdevice->write_then_read(addrbuffer, _addrwidth, buffer, len);
207224
}
208225
if (_spidevice) {
209226
if (_spiregtype == ADDRESSED_OPCODE_BIT0_LOW_TO_WRITE) {
210227
// very special case!
211-
212228
// pass the special opcode address which we set as the high byte of the
213229
// regaddr
214230
addrbuffer[0] =
@@ -230,6 +246,9 @@ bool Adafruit_BusIO_Register::read(uint8_t *buffer, uint8_t len) {
230246
}
231247
return _spidevice->write_then_read(addrbuffer, _addrwidth, buffer, len);
232248
}
249+
if (_genericdevice) {
250+
return _genericdevice->readRegister(addrbuffer, _addrwidth, buffer, len);
251+
}
233252
return false;
234253
}
235254

Adafruit_BusIO_Register.h

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
#if !defined(SPI_INTERFACES_COUNT) || \
77
(defined(SPI_INTERFACES_COUNT) && (SPI_INTERFACES_COUNT > 0))
88

9+
#include <Adafruit_GenericDevice.h>
910
#include <Adafruit_I2CDevice.h>
1011
#include <Adafruit_SPIDevice.h>
1112

@@ -57,6 +58,11 @@ class Adafruit_BusIO_Register {
5758
uint8_t width = 1, uint8_t byteorder = LSBFIRST,
5859
uint8_t address_width = 1);
5960

61+
Adafruit_BusIO_Register(Adafruit_GenericDevice *genericdevice,
62+
uint16_t reg_addr, uint8_t width = 1,
63+
uint8_t byteorder = LSBFIRST,
64+
uint8_t address_width = 1);
65+
6066
bool read(uint8_t *buffer, uint8_t len);
6167
bool read(uint8_t *value);
6268
bool read(uint16_t *value);
@@ -77,6 +83,7 @@ class Adafruit_BusIO_Register {
7783
private:
7884
Adafruit_I2CDevice *_i2cdevice;
7985
Adafruit_SPIDevice *_spidevice;
86+
Adafruit_GenericDevice *_genericdevice;
8087
Adafruit_BusIO_SPIRegType _spiregtype;
8188
uint16_t _address;
8289
uint8_t _width, _addrwidth, _byteorder;

Adafruit_GenericDevice.cpp

Lines changed: 78 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,78 @@
1+
/*
2+
Written with help by Claude!
3+
https://claude.ai/chat/335f50b1-3dd8-435e-9139-57ec7ca26a3c (at this time
4+
chats are not shareable :(
5+
*/
6+
7+
#include "Adafruit_GenericDevice.h"
8+
9+
/*! @brief Create a Generic device with the provided read/write functions
10+
@param read_func Function pointer for reading raw data
11+
@param write_func Function pointer for writing raw data
12+
@param readreg_func Function pointer for reading registers (optional)
13+
@param writereg_func Function pointer for writing registers (optional) */
14+
Adafruit_GenericDevice::Adafruit_GenericDevice(
15+
busio_genericdevice_read_t read_func,
16+
busio_genericdevice_write_t write_func,
17+
busio_genericdevice_readreg_t readreg_func,
18+
busio_genericdevice_writereg_t writereg_func) {
19+
_read_func = read_func;
20+
_write_func = write_func;
21+
_readreg_func = readreg_func;
22+
_writereg_func = writereg_func;
23+
_begun = false;
24+
}
25+
26+
/*! @brief Initializes the device
27+
@return true if initialization was successful, otherwise false */
28+
bool Adafruit_GenericDevice::begin(void) {
29+
_begun = true;
30+
return true;
31+
}
32+
33+
/*! @brief Write a buffer of data
34+
@param buffer Pointer to buffer of data to write
35+
@param len Number of bytes to write
36+
@return true if write was successful, otherwise false */
37+
bool Adafruit_GenericDevice::write(const uint8_t *buffer, size_t len) {
38+
if (!_begun)
39+
return false;
40+
return _write_func(buffer, len);
41+
}
42+
43+
/*! @brief Read data into a buffer
44+
@param buffer Pointer to buffer to read data into
45+
@param len Number of bytes to read
46+
@return true if read was successful, otherwise false */
47+
bool Adafruit_GenericDevice::read(uint8_t *buffer, size_t len) {
48+
if (!_begun)
49+
return false;
50+
return _read_func(buffer, len);
51+
}
52+
53+
/*! @brief Read from a register location
54+
@param addr_buf Buffer containing register address
55+
@param addrsiz Size of register address in bytes
56+
@param buf Buffer to store read data
57+
@param bufsiz Size of data to read in bytes
58+
@return true if read was successful, otherwise false */
59+
bool Adafruit_GenericDevice::readRegister(uint8_t *addr_buf, uint8_t addrsiz,
60+
uint8_t *buf, uint16_t bufsiz) {
61+
if (!_begun || !_readreg_func)
62+
return false;
63+
return _readreg_func(addr_buf, addrsiz, buf, bufsiz);
64+
}
65+
66+
/*! @brief Write to a register location
67+
@param addr_buf Buffer containing register address
68+
@param addrsiz Size of register address in bytes
69+
@param buf Buffer containing data to write
70+
@param bufsiz Size of data to write in bytes
71+
@return true if write was successful, otherwise false */
72+
bool Adafruit_GenericDevice::writeRegister(uint8_t *addr_buf, uint8_t addrsiz,
73+
const uint8_t *buf,
74+
uint16_t bufsiz) {
75+
if (!_begun || !_writereg_func)
76+
return false;
77+
return _writereg_func(addr_buf, addrsiz, buf, bufsiz);
78+
}

Adafruit_GenericDevice.h

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
#ifndef ADAFRUIT_GENERICDEVICE_H
2+
#define ADAFRUIT_GENERICDEVICE_H
3+
4+
#include <Arduino.h>
5+
6+
typedef bool (*busio_genericdevice_read_t)(uint8_t *buffer, size_t len);
7+
typedef bool (*busio_genericdevice_write_t)(const uint8_t *buffer, size_t len);
8+
typedef bool (*busio_genericdevice_readreg_t)(uint8_t *addr_buf,
9+
uint8_t addrsiz, uint8_t *buf,
10+
uint16_t bufsiz);
11+
typedef bool (*busio_genericdevice_writereg_t)(uint8_t *addr_buf,
12+
uint8_t addrsiz,
13+
const uint8_t *buf,
14+
uint16_t bufsiz);
15+
16+
/*!
17+
* @brief Class for communicating with a device via generic read/write functions
18+
*/
19+
class Adafruit_GenericDevice {
20+
public:
21+
Adafruit_GenericDevice(
22+
busio_genericdevice_read_t read_func,
23+
busio_genericdevice_write_t write_func,
24+
busio_genericdevice_readreg_t readreg_func = nullptr,
25+
busio_genericdevice_writereg_t writereg_func = nullptr);
26+
27+
bool begin(void);
28+
29+
bool read(uint8_t *buffer, size_t len);
30+
bool write(const uint8_t *buffer, size_t len);
31+
bool readRegister(uint8_t *addr_buf, uint8_t addrsiz, uint8_t *buf,
32+
uint16_t bufsiz);
33+
bool writeRegister(uint8_t *addr_buf, uint8_t addrsiz, const uint8_t *buf,
34+
uint16_t bufsiz);
35+
36+
protected:
37+
/*! @brief Function pointer for reading raw data from the device */
38+
busio_genericdevice_read_t _read_func;
39+
/*! @brief Function pointer for writing raw data to the device */
40+
busio_genericdevice_write_t _write_func;
41+
/*! @brief Function pointer for reading a 'register' from the device */
42+
busio_genericdevice_readreg_t _readreg_func;
43+
/*! @brief Function pointer for writing a 'register' to the device */
44+
busio_genericdevice_writereg_t _writereg_func;
45+
46+
bool _begun; ///< whether we have initialized yet (in case the function needs
47+
///< to do something)
48+
};
49+
50+
#endif // ADAFRUIT_GENERICDEVICE_H

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
# 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)
22

33

4-
This is a helper library to abstract away I2C & SPI transactions and registers
4+
This is a helper library to abstract away I2C, SPI, and 'generic transport' (e.g. UART) transactions and registers
55

66
Adafruit invests time and resources providing this open source code, please support Adafruit and open-source hardware by purchasing products from Adafruit!
77

examples/genericdevice_uartregtest/.uno.test.skip

Whitespace-only changes.

0 commit comments

Comments
 (0)