Code cleanup of external delay effect

master
Steve Lascos 7 years ago
parent 631392f0bf
commit a99e7aaca4
  1. 221
      src/BAAudioEffectDelayExternal.cpp
  2. 37
      src/BAAudioEffectDelayExternal.h
  3. 17
      src/BACommon.h
  4. 1
      src/BAGuitar.h
  5. 169
      src/BASpiMemory.cpp
  6. 4
      src/BASpiMemory.h

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

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

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

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

Loading…
Cancel
Save