diff --git a/src/BAHardware.h b/src/BAHardware.h index 0f13306..690b1da 100644 --- a/src/BAHardware.h +++ b/src/BAHardware.h @@ -57,6 +57,7 @@ enum class GPIO : uint8_t { /**************************************************************************//** * Optionally installed SPI RAM *****************************************************************************/ +constexpr unsigned NUM_MEM_SLOTS = 2; enum MemSelect : unsigned { MEM0 = 0, ///< SPI RAM MEM0 MEM1 = 1 ///< SPI RAM MEM1 diff --git a/src/BASpiMemory.cpp b/src/BASpiMemory.cpp index 36f9522..f618f86 100644 --- a/src/BASpiMemory.cpp +++ b/src/BASpiMemory.cpp @@ -96,7 +96,7 @@ BASpiMemory::~BASpiMemory() { } // Single address write -void BASpiMemory::write(int address, int data) +void BASpiMemory::write(size_t address, uint8_t data) { m_spi->beginTransaction(m_settings); digitalWrite(m_csPin, LOW); @@ -109,7 +109,42 @@ void BASpiMemory::write(int address, int data) digitalWrite(m_csPin, HIGH); } -void BASpiMemory::write16(int address, uint16_t data) +// Single address write +void BASpiMemory::write(size_t address, uint8_t *data, size_t numBytes) +{ + uint8_t *dataPtr = data; + + m_spi->beginTransaction(m_settings); + digitalWrite(m_csPin, LOW); + 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)); + + for (size_t i=0; i < numBytes; i++) { + m_spi->transfer(*dataPtr++); + } + m_spi->endTransaction(); + digitalWrite(m_csPin, HIGH); +} + +void BASpiMemory::zero(size_t address, size_t numBytes) +{ + m_spi->beginTransaction(m_settings); + digitalWrite(m_csPin, LOW); + 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)); + + for (size_t i=0; i < numBytes; i++) { + m_spi->transfer(0); + } + m_spi->endTransaction(); + digitalWrite(m_csPin, HIGH); +} + +void BASpiMemory::write16(size_t address, uint16_t data) { m_spi->beginTransaction(m_settings); digitalWrite(m_csPin, LOW); @@ -120,8 +155,40 @@ void BASpiMemory::write16(int address, uint16_t data) digitalWrite(m_csPin, HIGH); } +void BASpiMemory::write16(size_t address, uint16_t *data, size_t numWords) +{ + uint16_t *dataPtr = data; + + m_spi->beginTransaction(m_settings); + digitalWrite(m_csPin, LOW); + m_spi->transfer16((SPI_WRITE_CMD << 8) | (address >> 16) ); + m_spi->transfer16(address & 0xFFFF); + + for (size_t i=0; itransfer16(*dataPtr++); + } + + m_spi->endTransaction(); + digitalWrite(m_csPin, HIGH); +} + +void BASpiMemory::zero16(size_t address, size_t numWords) +{ + m_spi->beginTransaction(m_settings); + digitalWrite(m_csPin, LOW); + m_spi->transfer16((SPI_WRITE_CMD << 8) | (address >> 16) ); + m_spi->transfer16(address & 0xFFFF); + + for (size_t i=0; itransfer16(0); + } + + m_spi->endTransaction(); + digitalWrite(m_csPin, HIGH); +} + // single address read -int BASpiMemory::read(int address) +uint8_t BASpiMemory::read(size_t address) { int data; @@ -137,7 +204,27 @@ int BASpiMemory::read(int address) return data; } -uint16_t BASpiMemory::read16(int address) + +void BASpiMemory::read(size_t address, uint8_t *data, size_t numBytes) +{ + uint8_t *dataPtr = data; + + m_spi->beginTransaction(m_settings); + digitalWrite(m_csPin, LOW); + 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)); + + for (size_t i=0; itransfer(0); + } + + m_spi->endTransaction(); + digitalWrite(m_csPin, HIGH); +} + +uint16_t BASpiMemory::read16(size_t address) { uint16_t data; @@ -152,4 +239,21 @@ uint16_t BASpiMemory::read16(int address) return data; } +void BASpiMemory::read16(size_t address, uint16_t *data, size_t numWords) +{ + + uint16_t *dataPtr = data; + m_spi->beginTransaction(m_settings); + digitalWrite(m_csPin, LOW); + m_spi->transfer16((SPI_READ_CMD << 8) | (address >> 16) ); + m_spi->transfer16(address & 0xFFFF); + + for (size_t i=0; itransfer16(0); + } + + m_spi->endTransaction(); + digitalWrite(m_csPin, HIGH); +} + } /* namespace BAGuitar */ diff --git a/src/BASpiMemory.h b/src/BASpiMemory.h index fc5450e..d62c925 100644 --- a/src/BASpiMemory.h +++ b/src/BASpiMemory.h @@ -39,10 +39,10 @@ public: BASpiMemory() = delete; /// Create an object to control either MEM0 (via SPI1) or MEM1 (via SPI2). /// @details default is 20 Mhz - /// @param memDeviceId specify which MEM to controlw with SpiDeviceId. + /// @param memDeviceId specify which MEM to control with SpiDeviceId. BASpiMemory(SpiDeviceId memDeviceId); /// Create an object to control either MEM0 (via SPI1) or MEM1 (via SPI2) - /// @param memDeviceId specify which MEM to controlw with SpiDeviceId. + /// @param memDeviceId specify which MEM to control with SpiDeviceId. /// @param speedHz specify the desired speed in Hz. BASpiMemory(SpiDeviceId memDeviceId, uint32_t speedHz); virtual ~BASpiMemory(); @@ -52,19 +52,27 @@ public: /// 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 - void write(int address, int data); + void write(size_t address, uint8_t data); + void write(size_t address, uint8_t *data, size_t numBytes); + void zero(size_t address, size_t numBytes); - void write16(int address, uint16_t data); + void write16(size_t address, uint16_t data); + void write16(size_t address, uint16_t *data, size_t numBytes); + + void zero16(size_t address, size_t numBytes); /// read a single 8-bit data word from the specified address /// @param address the address in the SPI RAM to read from /// @return the data that was read - int read(int address); + uint8_t read(size_t address); + void read(size_t address, uint8_t *data, size_t numBytes); /// read a single 16-bit data word from the specified address /// @param address the address in the SPI RAM to read from /// @return the data that was read - uint16_t read16(int address); + uint16_t read16(size_t address); + void read16(size_t address, uint16_t *data, size_t numBytes); + private: SPIClass *m_spi = nullptr; diff --git a/src/LibBasicFunctions.cpp b/src/LibBasicFunctions.cpp new file mode 100644 index 0000000..59ce791 --- /dev/null +++ b/src/LibBasicFunctions.cpp @@ -0,0 +1,35 @@ +/* + * LibBasicFunctions.cpp + * + * Created on: Dec 23, 2017 + * Author: slascos + */ + +#include "LibBasicFunctions.h" + +namespace BAGuitar { + +void updateAudioMemorySlot(BASpiMemory *mem, MemSlot slot, audio_block_t *block) +{ + if (block) { + if (slot.currentPosition + AUDIO_BLOCK_SAMPLES-1 <= slot.end) { + // entire block fits in memory slot without wrapping + mem->write16(slot.currentPosition, (uint16_t *)block->data, AUDIO_BLOCK_SAMPLES); // cast audio data to uint. + } else { + // this write will wrap the memory slot + size_t numBytes = slot.end - slot.currentPosition + 1; + mem->write16(slot.currentPosition, (uint16_t *)block->data, numBytes); + size_t remainingBytes = AUDIO_BLOCK_SAMPLES - numBytes; // calculate the remaining bytes + mem->write16(slot.start, (uint16_t *)block->data + numBytes, remainingBytes); // write remaining bytes are start + } + } +} + + +void zeroMemorySlot(BASpiMemory *mem, MemSlot slot) +{ + mem->zero16(slot.start, slot.end-slot.start+1); +} + +} + diff --git a/src/LibBasicFunctions.h b/src/LibBasicFunctions.h new file mode 100644 index 0000000..e007cf0 --- /dev/null +++ b/src/LibBasicFunctions.h @@ -0,0 +1,23 @@ +/* + * LibBasicFunctions.h + * + * Created on: Dec 23, 2017 + * Author: slascos + */ + +#ifndef SRC_LIBBASICFUNCTIONS_H_ +#define SRC_LIBBASICFUNCTIONS_H_ + +#include "Audio.h" +#include "LibExtMemoryManagement.h" +#include "BASpiMemory.h" + +namespace BAGuitar { + +void updateAudioMemorySlot(BAGuitar::BASpiMemory *mem, MemSlot slot, audio_block_t *block); +void zeroMemorySlot(BAGuitar::BASpiMemory *mem, MemSlot slot); + +} + + +#endif /* SRC_LIBBASICFUNCTIONS_H_ */ diff --git a/src/LibExtMemoryManagement.h b/src/LibExtMemoryManagement.h new file mode 100644 index 0000000..7350d58 --- /dev/null +++ b/src/LibExtMemoryManagement.h @@ -0,0 +1,66 @@ +/* + * ExtMemoryManagement.h + * + * Created on: Dec 23, 2017 + * Author: slascos + */ + +#ifndef SRC_LIBEXTMEMORYMANAGEMENT_H_ +#define SRC_LIBEXTMEMORYMANAGEMENT_H_ + +#include + +#include "BAHardware.h" + +namespace BAGuitar { + +struct MemConfig { + size_t size; + size_t totalAvailable; + size_t nextAvailable; +}; + +struct MemSlot { + size_t start; + size_t end; + size_t currentPosition; +}; + +class ExternalSramManager { +public: + ExternalSramManager() = delete; + ExternalSramManager(BAGuitar::MemSelect mem) { + + // Initialize the static memory configuration structs + m_memConfig[MEM0].size = MEM0_MAX_ADDR; + m_memConfig[MEM0].totalAvailable = MEM0_MAX_ADDR; + m_memConfig[MEM0].nextAvailable = 0; + + m_memConfig[MEM0].size = MEM0_MAX_ADDR; + m_memConfig[MEM0].totalAvailable = MEM0_MAX_ADDR; + m_memConfig[MEM0].nextAvailable = 0; + } + + + bool getMemory(BAGuitar::MemSelect mem, size_t size, MemSlot &slot) { + if (m_memConfig[mem].totalAvailable >= size) { + slot.start = m_memConfig[mem].nextAvailable; + slot.end = slot.start + size -1; + slot.currentPosition = slot.start; + + // Update the mem config + m_memConfig[mem].nextAvailable = slot.end+1; + m_memConfig[mem].totalAvailable -= size; + return true; + } else { + return false; + } + } + + static MemConfig m_memConfig[BAGuitar::NUM_MEM_SLOTS]; + +}; + +} + +#endif /* SRC_LIBEXTMEMORYMANAGEMENT_H_ */