Added bulk transfer functions to BASpiMemory, and start work on some library routines for external SRAM management and. NOT WORKING YET

master
Steve Lascos 6 years ago
parent f3104753fc
commit ecb0ba0aa8
  1. 1
      src/BAHardware.h
  2. 112
      src/BASpiMemory.cpp
  3. 20
      src/BASpiMemory.h
  4. 35
      src/LibBasicFunctions.cpp
  5. 23
      src/LibBasicFunctions.h
  6. 66
      src/LibExtMemoryManagement.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

@ -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; i<numWords; i++) {
m_spi->transfer16(*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; i<numWords; i++) {
m_spi->transfer16(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; i<numBytes; i++) {
*dataPtr++ = m_spi->transfer(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; i<numWords; i++) {
*dataPtr++ = m_spi->transfer16(0);
}
m_spi->endTransaction();
digitalWrite(m_csPin, HIGH);
}
} /* namespace BAGuitar */

@ -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;

@ -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);
}
}

@ -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_ */

@ -0,0 +1,66 @@
/*
* ExtMemoryManagement.h
*
* Created on: Dec 23, 2017
* Author: slascos
*/
#ifndef SRC_LIBEXTMEMORYMANAGEMENT_H_
#define SRC_LIBEXTMEMORYMANAGEMENT_H_
#include <cstddef>
#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_ */
Loading…
Cancel
Save