Skip to content

Commit fd2bfa1

Browse files
authored
Merge pull request #29 from bcmi-labs/busio-style-interface
Provide Adafruit_BusIO style interface for Wire/SPI
2 parents e3e793f + 1fae13f commit fd2bfa1

14 files changed

+378
-45
lines changed

examples/Threadsafe_SPI/Threadsafe_SPI.ino

+4-9
Original file line numberDiff line numberDiff line change
@@ -60,22 +60,17 @@ void loop()
6060

6161
byte bmp388_read_reg(byte const reg_addr)
6262
{
63-
byte const write_buf[3] =
64-
{
65-
static_cast<byte>(0x80 | reg_addr), /* REG_ADDR, if MSBit is set -> READ access */
66-
0, /* Dummy byte. */
67-
0 /* REG_VAL is output on SDO */
68-
};
69-
byte read_buf[3] = {0};
63+
/* REG_ADDR | DUMMY_BYTE | REG_VAL is on SDO */
64+
byte read_write_buf[] = {static_cast<byte>(0x80 | reg_addr), 0, 0};
7065

71-
IoRequest req(write_buf, sizeof(write_buf), read_buf, sizeof(read_buf));
66+
IoRequest req(read_write_buf, sizeof(read_write_buf), nullptr, 0);
7267
IoResponse rsp = bmp388.transfer(req);
7368

7469
/* Do other stuff */
7570

7671
rsp->wait();
7772

78-
return read_buf[2];
73+
return read_write_buf[2];
7974
}
8075

8176
void bmp388_thread_func()
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,84 @@
1+
/**************************************************************************************
2+
* INCLUDE
3+
**************************************************************************************/
4+
5+
#include <Arduino_ThreadsafeIO.h>
6+
7+
/**************************************************************************************
8+
* CONSTANTS
9+
**************************************************************************************/
10+
11+
static int const BMP388_CS_PIN = 2;
12+
static int const BMP388_INT_PIN = 6;
13+
static byte const BMP388_CHIP_ID_REG_ADDR = 0x00;
14+
15+
static size_t constexpr NUM_THREADS = 20;
16+
17+
/**************************************************************************************
18+
* FUNCTION DECLARATION
19+
**************************************************************************************/
20+
21+
byte bmp388_read_reg(byte const reg_addr);
22+
void bmp388_thread_func();
23+
24+
/**************************************************************************************
25+
* GLOBAL VARIABLES
26+
**************************************************************************************/
27+
28+
BusDevice bmp388(SPI, BMP388_CS_PIN, 1000000, MSBFIRST, SPI_MODE0);
29+
30+
static char thread_name[NUM_THREADS][32];
31+
32+
/**************************************************************************************
33+
* SETUP/LOOP
34+
**************************************************************************************/
35+
36+
void setup()
37+
{
38+
Serial.begin(9600);
39+
while (!Serial) { }
40+
41+
pinMode(BMP388_CS_PIN, OUTPUT);
42+
digitalWrite(BMP388_CS_PIN, HIGH);
43+
44+
for(size_t i = 0; i < NUM_THREADS; i++)
45+
{
46+
snprintf(thread_name[i], sizeof(thread_name[i]), "Thread #%02d", i);
47+
rtos::Thread * t = new rtos::Thread(osPriorityNormal, OS_STACK_SIZE, nullptr, thread_name[i]);
48+
t->start(bmp388_thread_func);
49+
}
50+
}
51+
52+
void loop()
53+
{
54+
55+
}
56+
57+
/**************************************************************************************
58+
* FUNCTION DEFINITION
59+
**************************************************************************************/
60+
61+
byte bmp388_read_reg(byte const reg_addr)
62+
{
63+
/* REG_ADDR | DUMMY_BYTE | REG_VAL is on SDO */
64+
byte write_buf[2] = {static_cast<byte>(0x80 | reg_addr), 0};
65+
byte read_buf = 0;
66+
67+
bmp388.spi().write_then_read(write_buf, sizeof(write_buf), &read_buf, sizeof(read_buf));
68+
return read_buf;
69+
}
70+
71+
void bmp388_thread_func()
72+
{
73+
for(;;)
74+
{
75+
/* Sleep between 5 and 500 ms */
76+
rtos::ThisThread::sleep_for(rtos::Kernel::Clock::duration_u32(random(5,500)));
77+
/* Try to read some data from the BMP3888. */
78+
byte const chip_id = bmp388_read_reg(BMP388_CHIP_ID_REG_ADDR);
79+
/* Print thread id and chip id value to serial. */
80+
char msg[64] = {0};
81+
snprintf(msg, sizeof(msg), "%s: Chip ID = 0x%X", rtos::ThisThread::get_name(), chip_id);
82+
Serial.println(msg);
83+
}
84+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,78 @@
1+
/**************************************************************************************
2+
* INCLUDE
3+
**************************************************************************************/
4+
5+
#include <Arduino_ThreadsafeIO.h>
6+
7+
/**************************************************************************************
8+
* CONSTANTS
9+
**************************************************************************************/
10+
11+
static byte constexpr LSM6DSOX_ADDRESS = 0x6A;
12+
static byte constexpr LSM6DSOX_WHO_AM_I_REG = 0x0F;
13+
14+
static size_t constexpr NUM_THREADS = 20;
15+
16+
/**************************************************************************************
17+
* FUNCTION DECLARATION
18+
**************************************************************************************/
19+
20+
byte lsm6dsox_read_reg(byte const reg_addr);
21+
void lsm6dsox_thread_func();
22+
23+
/**************************************************************************************
24+
* GLOBAL VARIABLES
25+
**************************************************************************************/
26+
27+
BusDevice lsm6dsox(Wire, LSM6DSOX_ADDRESS);
28+
29+
static char thread_name[NUM_THREADS][32];
30+
31+
/**************************************************************************************
32+
* SETUP/LOOP
33+
**************************************************************************************/
34+
35+
void setup()
36+
{
37+
Serial.begin(9600);
38+
while (!Serial) { }
39+
40+
/* Fire up some threads all accessing the LSM6DSOX */
41+
for(size_t i = 0; i < NUM_THREADS; i++)
42+
{
43+
snprintf(thread_name[i], sizeof(thread_name[i]), "Thread #%02d", i);
44+
rtos::Thread * t = new rtos::Thread(osPriorityNormal, OS_STACK_SIZE, nullptr, thread_name[i]);
45+
t->start(lsm6dsox_thread_func);
46+
}
47+
}
48+
49+
void loop()
50+
{
51+
52+
}
53+
54+
/**************************************************************************************
55+
* FUNCTION DEFINITION
56+
**************************************************************************************/
57+
58+
byte lsm6dsox_read_reg(byte reg_addr)
59+
{
60+
byte read_buf = 0;
61+
lsm6dsox.wire().write_then_read(&reg_addr, 1, &read_buf, 1);
62+
return read_buf;
63+
}
64+
65+
void lsm6dsox_thread_func()
66+
{
67+
for(;;)
68+
{
69+
/* Sleep between 5 and 500 ms */
70+
rtos::ThisThread::sleep_for(rtos::Kernel::Clock::duration_u32(random(5,500)));
71+
/* Try to read some data from the LSM6DSOX. */
72+
byte const who_am_i = lsm6dsox_read_reg(LSM6DSOX_WHO_AM_I_REG);
73+
/* Print thread id and chip id value to serial. */
74+
char msg[64] = {0};
75+
snprintf(msg, sizeof(msg), "%s: LSM6DSOX[WHO_AM_I] = 0x%X", rtos::ThisThread::get_name(), who_am_i);
76+
Serial.println(msg);
77+
}
78+
}

keywords.txt

+5
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,11 @@ block KEYWORD2
2424
unblock KEYWORD2
2525
prefix KEYWORD2
2626
suffix KEYWORD2
27+
spi KEYWORD2
28+
wire KEYWORD2
29+
read KEYWORD2
30+
write KEYWORD2
31+
write_then_read KEYWORD2
2732

2833
#######################################
2934
# Constants (LITERAL1)

src/BusDevice.cpp

+10
Original file line numberDiff line numberDiff line change
@@ -109,3 +109,13 @@ IoResponse BusDevice::transfer(IoRequest & req)
109109
{
110110
return _dev->transfer(req);
111111
}
112+
113+
SpiBusDevice & BusDevice::spi()
114+
{
115+
return *reinterpret_cast<SpiBusDevice *>(_dev.get());
116+
}
117+
118+
WireBusDevice & BusDevice::wire()
119+
{
120+
return *reinterpret_cast<WireBusDevice *>(_dev.get());
121+
}

src/BusDevice.h

+6
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,8 @@ namespace arduino
3838
}
3939

4040
class BusDevice;
41+
class SpiBusDevice;
42+
class WireBusDevice;
4143

4244
/**************************************************************************************
4345
* CLASS DECLARATION
@@ -79,6 +81,10 @@ class BusDevice
7981
IoResponse transfer(IoRequest & req);
8082

8183

84+
SpiBusDevice & spi();
85+
WireBusDevice & wire();
86+
87+
8288
private:
8389

8490
mbed::SharedPtr<BusDeviceBase> _dev;

src/IoTransaction.h

+3-3
Original file line numberDiff line numberDiff line change
@@ -41,18 +41,18 @@ class IoRequest
4141
{
4242
public:
4343

44-
IoRequest(byte const * const write_buf_, size_t const bytes_to_write_, byte * read_buf_, size_t const bytes_to_read_)
44+
IoRequest(byte * write_buf_, size_t const bytes_to_write_, byte * read_buf_, size_t const bytes_to_read_)
4545
: write_buf{write_buf_}
4646
, bytes_to_write{bytes_to_write_}
4747
, read_buf{read_buf_}
4848
, bytes_to_read{bytes_to_read_}
4949
{ }
5050

51-
IoRequest(byte const & write_buf_, byte & read_buf_)
51+
IoRequest(byte & write_buf_, byte & read_buf_)
5252
: IoRequest{&write_buf_, 1, &read_buf_, 1}
5353
{ }
5454

55-
byte const * const write_buf{nullptr};
55+
byte * write_buf{nullptr};
5656
size_t const bytes_to_write{0};
5757
byte * read_buf{nullptr};
5858
size_t const bytes_to_read{0};

src/spi/SpiBusDevice.cpp

+70
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,70 @@
1+
/*
2+
* This file is part of the Arduino_ThreadsafeIO library.
3+
* Copyright (c) 2021 Arduino SA.
4+
*
5+
* This library is free software; you can redistribute it and/or
6+
* modify it under the terms of the GNU Lesser General Public
7+
* License as published by the Free Software Foundation; either
8+
* version 2.1 of the License, or (at your option) any later version.
9+
* This library is distributed in the hope that it will be useful,
10+
* but WITHOUT ANY WARRANTY; without even the implied warranty of
11+
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12+
* Lesser General Public License for more details.
13+
*
14+
* You should have received a copy of the GNU Lesser General Public
15+
* License along with this library; if not, write to the Free Software
16+
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
17+
*/
18+
19+
/**************************************************************************************
20+
* INCLUDE
21+
**************************************************************************************/
22+
23+
#include "SpiBusDevice.h"
24+
25+
#include "SpiDispatcher.h"
26+
27+
/**************************************************************************************
28+
* CTOR/DTOR
29+
**************************************************************************************/
30+
31+
SpiBusDevice::SpiBusDevice(SpiBusDeviceConfig const & config)
32+
: _config{config}
33+
{
34+
35+
}
36+
37+
/**************************************************************************************
38+
* PUBLIC MEMBER FUNCTIONS
39+
**************************************************************************************/
40+
41+
IoResponse SpiBusDevice::transfer(IoRequest & req)
42+
{
43+
return SpiDispatcher::instance().dispatch(&req, &_config);
44+
}
45+
46+
bool SpiBusDevice::read(uint8_t * buffer, size_t len, uint8_t sendvalue)
47+
{
48+
SpiBusDeviceConfig config(_config.spi(), _config.settings(), _config.select_func(), _config.deselect_func(), sendvalue);
49+
IoRequest req(nullptr, 0, buffer, len);
50+
IoResponse rsp = SpiDispatcher::instance().dispatch(&req, &config);
51+
rsp->wait();
52+
return true;
53+
}
54+
55+
bool SpiBusDevice::write(uint8_t * buffer, size_t len)
56+
{
57+
IoRequest req(buffer, len, nullptr, 0);
58+
IoResponse rsp = SpiDispatcher::instance().dispatch(&req, &_config);
59+
rsp->wait();
60+
return true;
61+
}
62+
63+
bool SpiBusDevice::write_then_read(uint8_t * write_buffer, size_t write_len, uint8_t * read_buffer, size_t read_len, uint8_t sendvalue)
64+
{
65+
SpiBusDeviceConfig config(_config.spi(), _config.settings(), _config.select_func(), _config.deselect_func(), sendvalue);
66+
IoRequest req(write_buffer, write_len, read_buffer, read_len);
67+
IoResponse rsp = SpiDispatcher::instance().dispatch(&req, &config);
68+
rsp->wait();
69+
return true;
70+
}

src/spi/SpiBusDevice.h

+8-11
Original file line numberDiff line numberDiff line change
@@ -23,12 +23,8 @@
2323
* INCLUDE
2424
**************************************************************************************/
2525

26-
#include <Arduino.h>
27-
#include <mbed.h>
28-
2926
#include "../BusDevice.h"
3027

31-
#include "SpiDispatcher.h"
3228
#include "SpiBusDeviceConfig.h"
3329

3430
/**************************************************************************************
@@ -39,15 +35,16 @@ class SpiBusDevice : public BusDeviceBase
3935
{
4036
public:
4137

42-
SpiBusDevice(SpiBusDeviceConfig const & config)
43-
: _config{config}
44-
{ }
38+
SpiBusDevice(SpiBusDeviceConfig const & config);
39+
virtual ~SpiBusDevice() { }
40+
41+
42+
virtual IoResponse transfer(IoRequest & req) override;
4543

4644

47-
virtual IoResponse transfer(IoRequest & req) override
48-
{
49-
return SpiDispatcher::instance().dispatch(&req, &_config);
50-
}
45+
bool read(uint8_t * buffer, size_t len, uint8_t sendvalue = 0xFF);
46+
bool write(uint8_t * buffer, size_t len);
47+
bool write_then_read(uint8_t * write_buffer, size_t write_len, uint8_t * read_buffer, size_t read_len, uint8_t sendvalue = 0xFF);
5148

5249

5350
private:

src/spi/SpiBusDeviceConfig.h

+2
Original file line numberDiff line numberDiff line change
@@ -66,6 +66,8 @@ class SpiBusDeviceConfig
6666
void deselect () const { if (_spi_deselect) _spi_deselect(); }
6767
byte fill_symbol() const { return _fill_symbol; }
6868

69+
SpiSelectFunc select_func () const { return _spi_select; }
70+
SpiDeselectFunc deselect_func() const { return _spi_deselect; }
6971

7072
private:
7173

0 commit comments

Comments
 (0)