Code cleanup of external delay effect

pull/1/head
Steve Lascos 7 years ago
parent 631392f0bf
commit a99e7aaca4
  1. 197
      src/BAAudioEffectDelayExternal.cpp
  2. 37
      src/BAAudioEffectDelayExternal.h
  3. 17
      src/BACommon.h
  4. 1
      src/BAGuitar.h
  5. 159
      src/BASpiMemory.cpp
  6. 4
      src/BASpiMemory.h

@ -22,7 +22,6 @@
namespace BAGuitar {
#define SPISETTING SPISettings(20000000, MSBFIRST, SPI_MODE0)
struct MemSpiConfig {
@ -39,35 +38,47 @@ constexpr MemSpiConfig Mem1Config = {21, 5, 20, 31, 65536 };
unsigned BAAudioEffectDelayExternal::m_usingSPICount[2] = {0,0};
BAAudioEffectDelayExternal::BAAudioEffectDelayExternal()
: AudioStream(1, inputQueueArray)
: AudioStream(1, m_inputQueueArray)
{
initialize(MemSelect::MEM0);
}
BAAudioEffectDelayExternal::BAAudioEffectDelayExternal(MemSelect mem)
: AudioStream(1, inputQueueArray)
: AudioStream(1, m_inputQueueArray)
{
initialize(mem);
}
BAAudioEffectDelayExternal::BAAudioEffectDelayExternal(BAGuitar::MemSelect type, float delayLengthMs)
: AudioStream(1, m_inputQueueArray)
{
unsigned delayLengthInt = (delayLengthMs*(AUDIO_SAMPLE_RATE_EXACT/1000.0f))+0.5f;
initialize(type, delayLengthInt);
}
BAAudioEffectDelayExternal::~BAAudioEffectDelayExternal()
{
if (m_spi) delete m_spi;
}
void BAAudioEffectDelayExternal::delay(uint8_t channel, float milliseconds) {
if (channel >= 8) return;
if (milliseconds < 0.0) milliseconds = 0.0;
uint32_t n = (milliseconds*(AUDIO_SAMPLE_RATE_EXACT/1000.0f))+0.5f;
n += AUDIO_BLOCK_SAMPLES;
if (n > memory_length - AUDIO_BLOCK_SAMPLES)
n = memory_length - AUDIO_BLOCK_SAMPLES;
delay_length[channel] = n;
uint8_t mask = activemask;
if (activemask == 0) m_startUsingSPI(m_spiChannel);
activemask = mask | (1<<channel);
if (n > m_memoryLength - AUDIO_BLOCK_SAMPLES)
n = m_memoryLength - AUDIO_BLOCK_SAMPLES;
m_channelDelayLength[channel] = n;
unsigned mask = m_activeMask;
if (m_activeMask == 0) m_startUsingSPI(m_spiChannel);
m_activeMask = mask | (1<<channel);
}
void BAAudioEffectDelayExternal::disable(uint8_t channel) {
if (channel >= 8) return;
uint8_t mask = activemask & ~(1<<channel);
activemask = mask;
uint8_t mask = m_activeMask & ~(1<<channel);
m_activeMask = mask;
if (mask == 0) m_stopUsingSPI(m_spiChannel);
}
@ -80,49 +91,49 @@ void BAAudioEffectDelayExternal::update(void)
block = receiveReadOnly();
if (block) {
if (head_offset + AUDIO_BLOCK_SAMPLES <= memory_length) {
if (m_headOffset + AUDIO_BLOCK_SAMPLES <= m_memoryLength) {
// a single write is enough
write(head_offset, AUDIO_BLOCK_SAMPLES, block->data);
head_offset += AUDIO_BLOCK_SAMPLES;
write(m_headOffset, AUDIO_BLOCK_SAMPLES, block->data);
m_headOffset += AUDIO_BLOCK_SAMPLES;
} else {
// write wraps across end-of-memory
n = memory_length - head_offset;
write(head_offset, n, block->data);
head_offset = AUDIO_BLOCK_SAMPLES - n;
write(0, head_offset, block->data + n);
n = m_memoryLength - m_headOffset;
write(m_headOffset, n, block->data);
m_headOffset = AUDIO_BLOCK_SAMPLES - n;
write(0, m_headOffset, block->data + n);
}
release(block);
} else {
// if no input, store zeros, so later playback will
// not be random garbage previously stored in memory
if (head_offset + AUDIO_BLOCK_SAMPLES <= memory_length) {
zero(head_offset, AUDIO_BLOCK_SAMPLES);
head_offset += AUDIO_BLOCK_SAMPLES;
if (m_headOffset + AUDIO_BLOCK_SAMPLES <= m_memoryLength) {
zero(m_headOffset, AUDIO_BLOCK_SAMPLES);
m_headOffset += AUDIO_BLOCK_SAMPLES;
} else {
n = memory_length - head_offset;
zero(head_offset, n);
head_offset = AUDIO_BLOCK_SAMPLES - n;
zero(0, head_offset);
n = m_memoryLength - m_headOffset;
zero(m_headOffset, n);
m_headOffset = AUDIO_BLOCK_SAMPLES - n;
zero(0, m_headOffset);
}
}
// transmit the delayed outputs
for (channel = 0; channel < 8; channel++) {
if (!(activemask & (1<<channel))) continue;
if (!(m_activeMask & (1<<channel))) continue;
block = allocate();
if (!block) continue;
// compute the delayed location where we read
if (delay_length[channel] <= head_offset) {
read_offset = head_offset - delay_length[channel];
if (m_channelDelayLength[channel] <= m_headOffset) {
read_offset = m_headOffset - m_channelDelayLength[channel];
} else {
read_offset = memory_length + head_offset - delay_length[channel];
read_offset = m_memoryLength + m_headOffset - m_channelDelayLength[channel];
}
if (read_offset + AUDIO_BLOCK_SAMPLES <= memory_length) {
if (read_offset + AUDIO_BLOCK_SAMPLES <= m_memoryLength) {
// a single read will do it
read(read_offset, AUDIO_BLOCK_SAMPLES, block->data);
} else {
// read wraps across end-of-memory
n = memory_length - read_offset;
n = m_memoryLength - read_offset;
read(read_offset, n, block->data);
read(0, AUDIO_BLOCK_SAMPLES - n, block->data + n);
}
@ -131,138 +142,106 @@ void BAAudioEffectDelayExternal::update(void)
}
}
uint32_t BAAudioEffectDelayExternal::allocated[2] = {0, 0};
unsigned BAAudioEffectDelayExternal::m_allocated[2] = {0, 0};
void BAAudioEffectDelayExternal::initialize(MemSelect mem)
void BAAudioEffectDelayExternal::initialize(MemSelect mem, unsigned delayLength)
{
uint32_t samples = 0;
uint32_t memsize, avail;
unsigned samples = 0;
unsigned memsize, avail;
activemask = 0;
head_offset = 0;
memsize = 65536;
m_activeMask = 0;
m_headOffset = 0;
m_mem = mem;
switch (mem) {
case MemSelect::MEM0 :
{
samples = Mem0Config.memSize;
memsize = Mem0Config.memSize;
m_spi = &SPI;
m_spiChannel = 0;
m_misoPin = Mem0Config.misoPin;
m_mosiPin = Mem0Config.mosiPin;
m_sckPin = Mem0Config.sckPin;
m_csPin = Mem0Config.csPin;
SPI.setMOSI(m_mosiPin);
SPI.setMISO(m_misoPin);
SPI.setSCK(m_sckPin);
SPI.begin();
m_spi->setMOSI(m_mosiPin);
m_spi->setMISO(m_misoPin);
m_spi->setSCK(m_sckPin);
m_spi->begin();
break;
}
case MemSelect::MEM1 :
{
#if defined(__MK64FX512__) || defined(__MK66FX1M0__)
memsize = Mem1Config.memSize;
m_spi = &SPI1;
m_spiChannel = 1;
samples = Mem1Config.memSize;
m_misoPin = Mem1Config.misoPin;
m_mosiPin = Mem1Config.mosiPin;
m_sckPin = Mem1Config.sckPin;
m_csPin = Mem1Config.csPin;
SPI1.setMOSI(m_mosiPin);
SPI1.setMISO(m_misoPin);
SPI1.setSCK(m_sckPin);
SPI1.begin();
m_spi->setMOSI(m_mosiPin);
m_spi->setMISO(m_misoPin);
m_spi->setSCK(m_sckPin);
m_spi->begin();
#endif
break;
}
}
pinMode(m_csPin, OUTPUT);
digitalWriteFast(m_csPin, HIGH);
avail = memsize - allocated[mem];
avail = memsize - m_allocated[mem];
if (samples > avail) samples = avail;
memory_begin = allocated[mem];
allocated[mem] += samples;
memory_length = samples;
if (delayLength > avail) samples = avail;
m_memoryStart = m_allocated[mem];
m_allocated[mem] += samples;
m_memoryLength = samples;
zero(0, m_memoryLength);
zero(0, memory_length);
}
void BAAudioEffectDelayExternal::read(uint32_t offset, uint32_t count, int16_t *data)
{
uint32_t addr = memory_begin + offset;
uint32_t addr = m_memoryStart + offset;
addr *= 2;
switch(m_mem) {
case MemSelect::MEM0 :
SPI.beginTransaction(SPISETTING);
m_spi->beginTransaction(SPISETTING);
digitalWriteFast(m_csPin, LOW);
SPI.transfer16((0x03 << 8) | (addr >> 16));
SPI.transfer16(addr & 0xFFFF);
m_spi->transfer16((0x03 << 8) | (addr >> 16));
m_spi->transfer16(addr & 0xFFFF);
while (count) {
*data++ = (int16_t)(SPI.transfer16(0));
*data++ = (int16_t)(m_spi->transfer16(0));
count--;
}
digitalWriteFast(m_csPin, HIGH);
SPI.endTransaction();
break;
case MemSelect::MEM1 :
SPI1.beginTransaction(SPISETTING);
digitalWriteFast(m_csPin, LOW);
SPI1.transfer16((0x03 << 8) | (addr >> 16));
SPI1.transfer16(addr & 0xFFFF);
while (count) {
*data++ = (int16_t)(SPI1.transfer16(0));
count--;
}
digitalWriteFast(m_csPin, HIGH);
SPI1.endTransaction();
break;
}
m_spi->endTransaction();
}
void BAAudioEffectDelayExternal::write(uint32_t offset, uint32_t count, const int16_t *data)
{
uint32_t addr = memory_begin + offset;
uint32_t addr = m_memoryStart + offset;
switch(m_mem) {
case MemSelect::MEM0 :
addr *= 2;
SPI.beginTransaction(SPISETTING);
m_spi->beginTransaction(SPISETTING);
digitalWriteFast(m_csPin, LOW);
SPI.transfer16((0x02 << 8) | (addr >> 16));
SPI.transfer16(addr & 0xFFFF);
m_spi->transfer16((0x02 << 8) | (addr >> 16));
m_spi->transfer16(addr & 0xFFFF);
while (count) {
int16_t w = 0;
if (data) w = *data++;
SPI.transfer16(w);
m_spi->transfer16(w);
count--;
}
digitalWriteFast(m_csPin, HIGH);
SPI.endTransaction();
break;
case MemSelect::MEM1 :
addr *= 2;
SPI1.beginTransaction(SPISETTING);
digitalWriteFast(m_csPin, LOW);
SPI1.transfer16((0x02 << 8) | (addr >> 16));
SPI1.transfer16(addr & 0xFFFF);
while (count) {
int16_t w = 0;
if (data) w = *data++;
SPI1.transfer16(w);
count--;
}
digitalWriteFast(m_csPin, HIGH);
SPI1.endTransaction();
break;
}
m_spi->endTransaction();
}
@ -276,9 +255,9 @@ void BAAudioEffectDelayExternal::zero(uint32_t address, uint32_t count) {
#ifdef SPI_HAS_NOTUSINGINTERRUPT
inline void BAAudioEffectDelayExternal::m_startUsingSPI(int spiBus) {
if (spiBus == 0) {
SPI.usingInterrupt(IRQ_SOFTWARE);
m_spi->usingInterrupt(IRQ_SOFTWARE);
} else if (spiBus == 1) {
SPI1.usingInterrupt(IRQ_SOFTWARE);
m_spi->usingInterrupt(IRQ_SOFTWARE);
}
m_usingSPICount[spiBus]++;
}
@ -287,9 +266,9 @@ inline void BAAudioEffectDelayExternal::m_stopUsingSPI(int spiBus) {
if (m_usingSPICount[spiBus] == 0 || --m_usingSPICount[spiBus] == 0)
{
if (spiBus == 0) {
SPI.notUsingInterrupt(IRQ_SOFTWARE);
m_spi->notUsingInterrupt(IRQ_SOFTWARE);
} else if (spiBus == 1) {
SPI1.notUsingInterrupt(IRQ_SOFTWARE);
m_spi->notUsingInterrupt(IRQ_SOFTWARE);
}
}
@ -298,9 +277,9 @@ inline void BAAudioEffectDelayExternal::m_stopUsingSPI(int spiBus) {
#else
inline void BAAudioEffectDelayExternal::m_startUsingSPI(int spiBus) {
if (spiBus == 0) {
SPI.usingInterrupt(IRQ_SOFTWARE);
m_spi->usingInterrupt(IRQ_SOFTWARE);
} else if (spiBus == 1) {
SPI1.usingInterrupt(IRQ_SOFTWARE);
m_spi->usingInterrupt(IRQ_SOFTWARE);
}
}

@ -9,16 +9,17 @@
#define __BAGUITAR_BAAUDIOEFFECTDELAYEXTERNAL_H
#include <Audio.h>
namespace BAGuitar {
#include "Arduino.h"
#include "AudioStream.h"
#include "spi_interrupt.h"
enum MemSelect {
MEM0,
MEM1,
#include "BACommon.h"
namespace BAGuitar {
enum MemSelect : unsigned {
MEM0 = 0,
MEM1 = 1
};
class BAAudioEffectDelayExternal : public AudioStream
@ -26,7 +27,9 @@ class BAAudioEffectDelayExternal : public AudioStream
public:
BAAudioEffectDelayExternal();
BAAudioEffectDelayExternal(MemSelect type);
BAAudioEffectDelayExternal(BAGuitar::MemSelect type);
BAAudioEffectDelayExternal(BAGuitar::MemSelect type, float delayLengthMs);
virtual ~BAAudioEffectDelayExternal();
void delay(uint8_t channel, float milliseconds);
void disable(uint8_t channel);
@ -35,22 +38,22 @@ public:
static unsigned m_usingSPICount[2];
private:
void initialize(MemSelect mem);
void initialize(BAGuitar::MemSelect mem, unsigned delayLength = 1e6);
void read(uint32_t address, uint32_t count, int16_t *data);
void write(uint32_t address, uint32_t count, const int16_t *data);
void zero(uint32_t address, uint32_t count);
uint32_t memory_begin; // the first address in the memory we're using
uint32_t memory_length; // the amount of memory we're using
uint32_t head_offset; // head index (incoming) data into external memory
uint32_t delay_length[8]; // # of sample delay for each channel (128 = no delay)
uint8_t activemask; // which output channels are active
//uint8_t memory_type; // 0=23LC1024, 1=Frank's Memoryboard
static uint32_t allocated[2];
audio_block_t *inputQueueArray[1];
unsigned m_memoryStart; // the first address in the memory we're using
unsigned m_memoryLength; // the amount of memory we're using
unsigned m_headOffset; // head index (incoming) data into external memory
unsigned m_channelDelayLength[8]; // # of sample delay for each channel (128 = no delay)
unsigned m_activeMask; // which output channels are active
static unsigned m_allocated[2];
audio_block_t *m_inputQueueArray[1];
MemSelect m_mem;
BAGuitar::MemSelect m_mem;
SPIClass *m_spi = nullptr;
int m_spiChannel = 0;
int m_misoPin = 0;
int m_mosiPin = 0;

@ -0,0 +1,17 @@
/*
* BACommon.h
*
* Created on: Nov 19, 2017
* Author: slascos
*/
#ifndef SRC_BACOMMON_H_
#define SRC_BACOMMON_H_
namespace BAGuitar {
constexpr int MEM0_MAX_ADDR = 131071; ///< Max address size per chip
constexpr int MEM1_MAX_ADDR = 131071; ///< Max address size per chip
}
#endif /* SRC_BACOMMON_H_ */

@ -31,6 +31,7 @@
*****************************************************************************/
namespace BAGuitar {
}
#endif /* SRC_BATGUITAR_H_ */

@ -45,42 +45,40 @@ constexpr int SPI_ADDR_1_SHIFT = 8;
constexpr int SPI_ADDR_0_MASK = 0x0000FF;
BASpiMemory::BASpiMemory(SpiDeviceId memDeviceId)
{
m_memDeviceId = memDeviceId;
m_settings = {20000000, MSBFIRST, SPI_MODE0};
m_Init();
}
BASpiMemory::BASpiMemory(SpiDeviceId memDeviceId, uint32_t speedHz)
{
m_memDeviceId = memDeviceId;
m_settings = {speedHz, MSBFIRST, SPI_MODE0};
m_Init();
}
// Intitialize the correct Arduino SPI interface
void BASpiMemory::m_Init()
void BASpiMemory::begin()
{
switch (m_memDeviceId) {
case SpiDeviceId::SPI_DEVICE0 :
m_csPin = SPI_CS_MEM0;
SPI.setMOSI(SPI_MOSI_MEM0);
SPI.setMISO(SPI_MISO_MEM0);
SPI.setSCK(SPI_SCK_MEM0);
SPI.begin();
m_spi = &SPI;
m_spi->setMOSI(SPI_MOSI_MEM0);
m_spi->setMISO(SPI_MISO_MEM0);
m_spi->setSCK(SPI_SCK_MEM0);
m_spi->begin();
break;
#if defined(__MK64FX512__) || defined(__MK66FX1M0__)
case SpiDeviceId::SPI_DEVICE1 :
m_csPin = SPI_CS_MEM1;
SPI1.setMOSI(SPI_MOSI_MEM1);
SPI1.setMISO(SPI_MISO_MEM1);
SPI1.setSCK(SPI_SCK_MEM1);
SPI1.begin();
m_spi = &SPI1;
m_spi->setMOSI(SPI_MOSI_MEM1);
m_spi->setMISO(SPI_MISO_MEM1);
m_spi->setSCK(SPI_SCK_MEM1);
m_spi->begin();
break;
#endif
@ -100,104 +98,41 @@ BASpiMemory::~BASpiMemory() {
// Single address write
void BASpiMemory::write(int address, int data)
{
switch (m_memDeviceId) {
case SpiDeviceId::SPI_DEVICE0 :
SPI.beginTransaction(m_settings);
digitalWrite(m_csPin, LOW);
SPI.transfer(SPI_WRITE_CMD);
SPI.transfer((address & SPI_ADDR_2_MASK) >> SPI_ADDR_2_SHIFT);
SPI.transfer((address & SPI_ADDR_1_MASK) >> SPI_ADDR_1_SHIFT);
SPI.transfer((address & SPI_ADDR_0_MASK));
SPI.transfer(data);
SPI.endTransaction();
break;
#if defined(__MK64FX512__) || defined(__MK66FX1M0__)
case SpiDeviceId::SPI_DEVICE1 :
SPI1.beginTransaction(m_settings);
m_spi->beginTransaction(m_settings);
digitalWrite(m_csPin, LOW);
SPI1.transfer(SPI_WRITE_CMD);
SPI1.transfer((address & SPI_ADDR_2_MASK) >> SPI_ADDR_2_SHIFT);
SPI1.transfer((address & SPI_ADDR_1_MASK) >> SPI_ADDR_1_SHIFT);
SPI1.transfer((address & SPI_ADDR_0_MASK));
SPI1.transfer(data);
SPI1.endTransaction();
break;
#endif
default :
break;
// unreachable
}
m_spi->transfer(SPI_WRITE_CMD);
m_spi->transfer((address & SPI_ADDR_2_MASK) >> SPI_ADDR_2_SHIFT);
m_spi->transfer((address & SPI_ADDR_1_MASK) >> SPI_ADDR_1_SHIFT);
m_spi->transfer((address & SPI_ADDR_0_MASK));
m_spi->transfer(data);
m_spi->endTransaction();
digitalWrite(m_csPin, HIGH);
}
void BASpiMemory::write16(int address, uint16_t data)
{
switch (m_memDeviceId) {
case SpiDeviceId::SPI_DEVICE0 :
SPI.beginTransaction(m_settings);
digitalWrite(m_csPin, LOW);
SPI.transfer16((SPI_WRITE_CMD << 8) | (address >> 16) );
SPI.transfer16(address & 0xFFFF);
SPI.transfer16(data);
SPI.endTransaction();
break;
#if defined(__MK64FX512__) || defined(__MK66FX1M0__)
case SpiDeviceId::SPI_DEVICE1 :
SPI1.beginTransaction(m_settings);
m_spi->beginTransaction(m_settings);
digitalWrite(m_csPin, LOW);
SPI1.transfer16((SPI_WRITE_CMD << 8) | (address >> 16) );
SPI1.transfer16(address & 0xFFFF);
SPI1.transfer16(data);
SPI1.endTransaction();
break;
#endif
default :
break;
// unreachable
}
m_spi->transfer16((SPI_WRITE_CMD << 8) | (address >> 16) );
m_spi->transfer16(address & 0xFFFF);
m_spi->transfer16(data);
m_spi->endTransaction();
digitalWrite(m_csPin, HIGH);
}
// single address read
int BASpiMemory::read(int address)
{
int data;
int data = -1;
switch (m_memDeviceId) {
case SpiDeviceId::SPI_DEVICE0 :
SPI.beginTransaction(m_settings);
digitalWrite(m_csPin, LOW);
SPI.transfer(SPI_READ_CMD);
SPI.transfer((address & SPI_ADDR_2_MASK) >> SPI_ADDR_2_SHIFT);
SPI.transfer((address & SPI_ADDR_1_MASK) >> SPI_ADDR_1_SHIFT);
SPI.transfer((address & SPI_ADDR_0_MASK));
data = SPI.transfer(0);
SPI.endTransaction();
break;
#if defined(__MK64FX512__) || defined(__MK66FX1M0__)
case SpiDeviceId::SPI_DEVICE1 :
SPI1.beginTransaction(m_settings);
m_spi->beginTransaction(m_settings);
digitalWrite(m_csPin, LOW);
SPI1.transfer(SPI_READ_CMD);
SPI1.transfer((address & SPI_ADDR_2_MASK) >> SPI_ADDR_2_SHIFT);
SPI1.transfer((address & SPI_ADDR_1_MASK) >> SPI_ADDR_1_SHIFT);
SPI1.transfer((address & SPI_ADDR_0_MASK));
data = SPI1.transfer(0);
SPI1.endTransaction();
break;
#endif
default:
break;
// unreachable
}
m_spi->transfer(SPI_READ_CMD);
m_spi->transfer((address & SPI_ADDR_2_MASK) >> SPI_ADDR_2_SHIFT);
m_spi->transfer((address & SPI_ADDR_1_MASK) >> SPI_ADDR_1_SHIFT);
m_spi->transfer((address & SPI_ADDR_0_MASK));
data = m_spi->transfer(0);
m_spi->endTransaction();
digitalWrite(m_csPin, HIGH);
return data;
}
@ -205,33 +140,13 @@ int BASpiMemory::read(int address)
uint16_t BASpiMemory::read16(int address)
{
uint16_t data=0;
switch (m_memDeviceId) {
case SpiDeviceId::SPI_DEVICE0 :
SPI.beginTransaction(m_settings);
uint16_t data;
m_spi->beginTransaction(m_settings);
digitalWrite(m_csPin, LOW);
SPI.transfer16((SPI_READ_CMD << 8) | (address >> 16) );
SPI.transfer16(address & 0xFFFF);
data = SPI.transfer16(0);
SPI.endTransaction();
break;
#if defined(__MK64FX512__) || defined(__MK66FX1M0__)
case SpiDeviceId::SPI_DEVICE1 :
SPI1.beginTransaction(m_settings);
digitalWrite(m_csPin, LOW);
SPI1.transfer16((SPI_READ_CMD << 8) | (address >> 16) );
SPI1.transfer16(address & 0xFFFF);
data = SPI1.transfer16(0);
SPI1.endTransaction();
break;
#endif
default:
break;
// unreachable
}
m_spi->transfer16((SPI_READ_CMD << 8) | (address >> 16) );
m_spi->transfer16(address & 0xFFFF);
data = m_spi->transfer16(0);
m_spi->endTransaction();
digitalWrite(m_csPin, HIGH);
return data;

@ -55,6 +55,8 @@ public:
BASpiMemory(SpiDeviceId memDeviceId, uint32_t speedHz);
virtual ~BASpiMemory();
void begin(void);
/// write a single data word to the specified address
/// @param address the address in the SPI RAM to write to
/// @param data the value to write
@ -69,10 +71,10 @@ public:
uint16_t read16(int address);
private:
SPIClass *m_spi = nullptr;
SpiDeviceId m_memDeviceId; // the MEM device being control with this instance
uint8_t m_csPin; // the IO pin number for the CS on the controlled SPI device
SPISettings m_settings; // the Wire settings for this SPI port
void m_Init();
};

Loading…
Cancel
Save