pull/19/head
Blackaddr 1 year ago
parent 167d8b82a1
commit 129e3a3e3b
  1. 35
      src/BAHardware.h
  2. 52
      src/LibMemoryManagement.h
  3. 74
      src/common/BAHardware.cpp
  4. 150
      src/common/ExtMemSlot.cpp
  5. 5
      src/common/ExternalSramManager.cpp

@ -40,7 +40,7 @@ enum class TgaBoard : unsigned {
REV_A = 0, ///< indicates using REV A of the TGA Pro
REV_B, ///< indicates using REV B of the TGA Pro
MKII_REV1, ///< indicates using MKII, Rev 1 of the TGA Pro
AVALON
MULTIVERSE ///< indicates using the Aviate Audio Multiverse
};
/// enum to specify the TGA Board revision
@ -54,7 +54,8 @@ enum class ExpansionBoard : unsigned {
NO_EXPANSION = 0, ///< default, indicates no expansion board is present
REV_1, ///< indicates using REV 1 of the Expansion Board
REV_2, ///< indicates using REV 2 of the Expansion Board
REV_3 ///< indicates using REV 3 of the Expansion Board (MKII Series)
REV_3, ///< indicates using REV 3 of the Expansion Board (MKII Series)
MULTIVERSE ///< indicates using the Aviate Audio Multiverse for controls
};
/// enum to specify SPI memory dize
@ -204,9 +205,12 @@ extern BAHardware BAHardwareConfig; ///< external definition of global configura
#define TGA_PRO_REVA(x) BALibrary::BAHardwareConfig.set(TgaBoard::REV_A) ///< Macro for specifying REV A of the TGA Pro
#define TGA_PRO_REVB(x) BALibrary::BAHardwareConfig.set(TgaBoard::REV_B) ///< Macro for specifying REV B of the TGA Pro
#define TGA_PRO_MKII_REV1(x) BALibrary::BAHardwareConfig.set(TgaBoard::MKII_REV1) ///< Macro for specifying REV B of the TGA Pro
#define MULTIVERSE(x) BALibrary::BAHardwareConfig.set(TgaBoard::MULTIVERSE) ///< Macro for specifying REV B of the TGA Pro
#define TGA_PRO_EXPAND_REV2(x) BALibrary::BAHardwareConfig.setExpansionBoard(ExpansionBoard::REV_2) ///< Macro for specifying REV 2 of the Expansion Board
#define TGA_PRO_EXPAND_REV3(x) BALibrary::BAHardwareConfig.setExpansionBoard(ExpansionBoard::REV_3) ///< Macro for specifying REV 2 of the Expansion Board
#define MULTIVERSE_EXPAND(x) BALibrary::BAHardwareConfig.setExpansionBoard(ExpansionBoard::MULTIVERSE) ///< Macro for specifying Multiverse
#define SPI_MEM0_1M(x) BALibrary::BAHardwareConfig.set(MEM0, SPI_MEMORY_1M) ///< Macro for specifying MEM0 is 1Mbit
#define SPI_MEM0_4M(x) BALibrary::BAHardwareConfig.set(MEM0, SPI_MEMORY_4M) ///< Macro for specifying MEM0 is 4Mbit
@ -228,9 +232,32 @@ extern uint8_t BA_EXPAND_POT3_PIN; // 16_A2_RX4_SCL1
extern uint8_t BA_EXPAND_SW1_PIN; // 2_OUT2
extern uint8_t BA_EXPAND_SW2_PIN; // 3_LRCLK2
extern uint8_t BA_EXPAND_LED1_PIN; // 4_BLCK2
extern uint8_t BA_EXPAND_LED2_PIN; // 5_IN2
// Only used on Aviate Audio Multiverse
// START Multiverse definitions
extern uint8_t BA_EXPAND_POT4_PIN;
extern uint8_t BA_EXPAND_POT5_PIN;
extern uint8_t BA_EXPAND_POT6_PIN;
extern uint8_t BA_EXPAND_SW3_PIN;
extern uint8_t BA_EXPAND_SW4_PIN;
extern uint8_t BA_EXPAND_SW5_PIN;
extern uint8_t BA_EXPAND_SW6_PIN;
extern uint8_t BA_EXPAND_ENC1_A_PIN;
extern uint8_t BA_EXPAND_ENC1_B_PIN;
extern uint8_t BA_EXPAND_ENC2_A_PIN;
extern uint8_t BA_EXPAND_ENC2_B_PIN;
extern uint8_t BA_EXPAND_ENC3_A_PIN;
extern uint8_t BA_EXPAND_ENC3_B_PIN;
extern uint8_t BA_EXPAND_ENC4_A_PIN;
extern uint8_t BA_EXPAND_ENC4_B_PIN;
// END Multiverse defintiions
extern uint8_t GPIO0;
extern uint8_t GPIO1;
extern uint8_t GPIO2;
@ -253,12 +280,12 @@ extern uint8_t SPI1_CS_PIN;
extern uint8_t SPI1_MISO_PIN;
extern uint8_t SPI1_MOSI_PIN;
#if defined(ARDUINO_TEENSY41) || defined(__MK66FX1M0__) || defined(__MK64FX512__)
#if defined(ARDUINO_TEENSY41) || defined(ARDUINO_TEENSY_MICROMOD) || defined(__MK66FX1M0__) || defined(__MK64FX512__)
#define SPI1_AVAILABLE
#endif
/**************************************************************************//**
* Teensy 4.0 Hardware Settings
* Teensy 4.X Hardware Settings
*****************************************************************************/
#if defined(__IMXRT1062__) // T4.0

@ -80,6 +80,55 @@ public:
/// @returns the read position value
size_t getReadPosition() const { return m_currentRdPosition-m_start; }
/* Byte-based transfers */
/// Write a block of zeros (8-bit) to the memory at the specified offset
/// @param offsetBytes offset in 8-bit bytes from start of slot
/// @param numBytes number of 8-bit bytes to transfer
/// @returns true on success, else false on error
bool zero(size_t offsetBytes, size_t numBytes);
/// Write a block of 8-bit data to the memory at the specified offset
/// @param offsetBytes offset in 8-bit bytes from start of slot
/// @param src pointer to start of block of 16-bit data
/// @param numBytes number of 8-bit bytes to transfer
/// @returns true on success, else false on error
bool write(size_t offsetBytes, uint8_t *src, size_t numBytes);
/// Read a block of 8-bit data from the memory at the specified location
/// @param offsetBytes offset in 8-bit bytes from start of slot
/// @param dest pointer to destination for the read data
/// @param numBytes number of 8-bit bytes to transfer
/// @returns true on success, else false on error
bool read(size_t offsetBytes, uint8_t *dest, size_t numBytes);
/// Write a block of 16-bit data zeros in circular operation
/// @param numBytes number of 16-bit words to transfer
/// @returns true on success, else false on error
bool zeroAdvance(size_t numBytes);
/// Write a single 16-bit data to the next location in circular operation
/// @param data the 16-bit word to transfer
/// @returns true on success, else false on error
bool writeAdvance(uint8_t data); // write just one data
/// Write a block of 16-bit data from the specified location in circular operation
/// @param src pointer to the start of the block of data to write to memory
/// @param numBytes number of 16-bit words to transfer
/// @returns true on success, else false on error
bool writeAdvance(uint8_t *src, size_t numBytes);
/// Read the next byte in memory during circular operation
/// @returns the next 8-bit data word in memory
uint8_t readAdvance();
/// Read the next block of numWords during circular operation
/// @details, dest is ignored when using DMA
/// @param dest pointer to the destination of the read.
/// @param numBytes number of 16-bit words to transfer
/// @returns true on success, else false on error
bool readAdvance(uint8_t *dest, size_t numBytes);
/// Write a block of 16-bit data to the memory at the specified offset
/// @param offsetWords offset in 16-bit words from start of slot
/// @param src pointer to start of block of 16-bit data
@ -100,11 +149,12 @@ public:
/// @returns true on success, else false on error
bool read16(size_t offsetWords, int16_t *dest, size_t numWords);
/* 16-bit data transfers */
/// Read the next in memory during circular operation
/// @returns the next 16-bit data word in memory
uint16_t readAdvance16();
/// Read the next block of numWords during circular operation
/// @details, dest is ignored when using DMA
/// @param dest pointer to the destination of the read.

@ -40,6 +40,7 @@ uint8_t BA_EXPAND_POT3_PIN = A2; // 16_A2_RX4_SCL1
uint8_t BA_EXPAND_SW1_PIN = 2; // 2_OUT2
uint8_t BA_EXPAND_SW2_PIN = 3; // 3_LRCLK2
uint8_t BA_EXPAND_LED1_PIN = 4; // 4_BLCK2
uint8_t BA_EXPAND_LED2_PIN = 5; // 5_IN2
@ -66,6 +67,27 @@ uint8_t SPI1_CS_PIN = 38;
uint8_t SPI1_MISO_PIN = 39;
uint8_t SPI1_MOSI_PIN = 26;
// The following pins are only used on Multiverse
// They have dummy default values
uint8_t BA_EXPAND_POT4_PIN = A0;
uint8_t BA_EXPAND_POT5_PIN = A0;
uint8_t BA_EXPAND_POT6_PIN = A0;
uint8_t BA_EXPAND_SW3_PIN = 0;
uint8_t BA_EXPAND_SW4_PIN = 0;
uint8_t BA_EXPAND_SW5_PIN = 0;
uint8_t BA_EXPAND_SW6_PIN = 0;
uint8_t BA_EXPAND_ENC1_A_PIN = 0;
uint8_t BA_EXPAND_ENC1_B_PIN = 0;
uint8_t BA_EXPAND_ENC2_A_PIN = 0;
uint8_t BA_EXPAND_ENC2_B_PIN = 0;
uint8_t BA_EXPAND_ENC3_A_PIN = 0;
uint8_t BA_EXPAND_ENC3_B_PIN = 0;
uint8_t BA_EXPAND_ENC4_A_PIN = 0;
uint8_t BA_EXPAND_ENC4_B_PIN = 0;
BAHardware::BAHardware()
{
#if defined(ARDUINO_TEENSY41) || defined(ARDUINO_TEENSY40) || defined(ARDUINO_TEENSY_MICROMOD) // T4.X
@ -88,6 +110,7 @@ void BAHardware::set(TgaBoard tgaBoard)
if (tgaBoard == TgaBoard::MKII_REV1) {
// No change from defaults
}
return;
#endif
#if defined(__MK66FX1M0__) || defined(__MK64FX512__) || defined(__MK20DX256__) // T3.6 or T3.5 or T3.2
@ -126,6 +149,7 @@ void BAHardware::set(TgaBoard tgaBoard)
SPI1_MISO_PIN = 5;
SPI1_MOSI_PIN = 21;
}
return;
#endif
////////////////////////////////////////////////////////////////////////////
@ -162,6 +186,7 @@ void BAHardware::set(TgaBoard tgaBoard)
SPI0_MISO_PIN = 12;
SPI0_MOSI_PIN = 11;
}
return;
#endif
#if defined(__MK66FX1M0__) || defined(__MK64FX512__) || defined(__MK20DX256__) // T3.6 or T3.5 or T3.2
@ -199,6 +224,7 @@ void BAHardware::set(TgaBoard tgaBoard)
SPI1_MISO_PIN = 5;
SPI1_MOSI_PIN = 21;
}
return;
#endif
////////////////////////////////////////////////////////////////////////////
@ -226,6 +252,7 @@ void BAHardware::set(TgaBoard tgaBoard)
SPI0_MISO_PIN = 12;
SPI0_MOSI_PIN = 11;
}
return;
#endif
#if defined(__MK66FX1M0__) || defined(__MK64FX512__) || defined(__MK20DX256__) // T3.6 or T3.5 or T3.2
@ -255,32 +282,57 @@ void BAHardware::set(TgaBoard tgaBoard)
SPI1_MISO_PIN = 5;
SPI1_MOSI_PIN = 21;
}
return;
#endif
////////////////////////////////////////////////////////////////////////////
// Avalon //
// MULTIVERSE //
////////////////////////////////////////////////////////////////////////////
#if defined(ARDUINO_TEENSY41) // T4.X
if (tgaBoard == TgaBoard::AVALON) {
BA_EXPAND_NUM_POT = 2;
#if defined(ARDUINO_TEENSY_MICROMOD)
if (tgaBoard == TgaBoard::MULTIVERSE) {
BA_EXPAND_NUM_POT = 4;
BA_EXPAND_NUM_SW = 6;
BA_EXPAND_NUM_LED = 2;
BA_EXPAND_NUM_ENC = 4;
BA_EXPAND_POT1_PIN = A0;
BA_EXPAND_POT2_PIN = A1;
BA_EXPAND_POT3_PIN = A13;
BA_EXPAND_POT1_PIN = A8;
BA_EXPAND_POT2_PIN = A0;
BA_EXPAND_POT3_PIN = A2;
BA_EXPAND_POT4_PIN = A3;
BA_EXPAND_SW1_PIN = 6;
BA_EXPAND_SW2_PIN = 34;
BA_EXPAND_SW3_PIN = 45;
BA_EXPAND_SW4_PIN = 32;
BA_EXPAND_SW5_PIN = 41;
BA_EXPAND_SW6_PIN = 40;
BA_EXPAND_SW1_PIN = 17;
BA_EXPAND_SW2_PIN = 16;
BA_EXPAND_LED1_PIN = 22;
BA_EXPAND_LED2_PIN = 32;
BA_EXPAND_ENC1_A_PIN = 33;
BA_EXPAND_ENC1_B_PIN = 2;
BA_EXPAND_ENC2_A_PIN = 31;
BA_EXPAND_ENC2_B_PIN = 36;
BA_EXPAND_ENC3_A_PIN = 5;
BA_EXPAND_ENC3_B_PIN = 4;
BA_EXPAND_ENC4_A_PIN = 3;
BA_EXPAND_ENC4_B_PIN = 30;
BA_EXPAND_LED1_PIN = 9;
BA_EXPAND_LED2_PIN = 42;
SPI0_SCK_PIN = 13;
SPI0_CS_PIN = 10;
SPI0_MISO_PIN = 12;
SPI0_MOSI_PIN = 11;
SPI1_SCK_PIN = 27;
SPI1_CS_PIN = 43;
SPI1_MISO_PIN = 1;
SPI1_MOSI_PIN = 26;
}
return;
#endif
}

@ -31,7 +31,7 @@ namespace BALibrary {
bool ExtMemSlot::clear()
{
if (!m_valid) { return false; }
m_spi->zero16(m_start, m_size);
m_spi->zero(m_start, m_size);
return true;
}
@ -43,13 +43,25 @@ bool ExtMemSlot::setWritePosition(size_t offsetBytes)
} else { return false; }
}
bool ExtMemSlot::write16(size_t offsetWords, int16_t *src, size_t numWords)
bool ExtMemSlot::setReadPosition(size_t offsetBytes)
{
if (m_start + offsetBytes <= m_end) {
m_currentRdPosition = m_start + offsetBytes;
return true;
} else {
return false;
}
}
/////////////////////////////////////////////////////////////////////////
// BYTE BASED TRANSFERS
/////////////////////////////////////////////////////////////////////////
bool ExtMemSlot::zero(size_t offsetBytes, size_t numBytes)
{
if (!m_valid) { return false; }
size_t writeStart = m_start + sizeof(int16_t)*offsetWords; // 2x because int16 is two bytes per data
size_t numBytes = sizeof(int16_t)*numWords;
size_t writeStart = m_start + offsetBytes;
if ((writeStart + numBytes-1) <= m_end) {
m_spi->write16(writeStart, reinterpret_cast<uint16_t*>(src), numWords); // cast audio data to uint
m_spi->zero(writeStart, numBytes); // cast audio data to uint
return true;
} else {
// this would go past the end of the memory slot, do not perform the write
@ -57,16 +69,138 @@ bool ExtMemSlot::write16(size_t offsetWords, int16_t *src, size_t numWords)
}
}
bool ExtMemSlot::setReadPosition(size_t offsetBytes)
bool ExtMemSlot::write(size_t offsetBytes, uint8_t *src, size_t numBytes)
{
if (m_start + offsetBytes <= m_end) {
m_currentRdPosition = m_start + offsetBytes;
if (!m_valid) { return false; }
size_t writeStart = m_start + offsetBytes;
if ((writeStart + numBytes-1) <= m_end) {
m_spi->write(writeStart, src, numBytes); // cast audio data to uint
return true;
} else {
// this would go past the end of the memory slot, do not perform the write
return false;
}
}
bool ExtMemSlot::read(size_t offsetBytes, uint8_t *dest, size_t numBytes)
{
if (!dest) return false; // invalid destination
size_t readOffset = m_start + offsetBytes;
if ((readOffset + numBytes-1) <= m_end) {
m_spi->read(readOffset, dest, numBytes);
return true;
} else {
// this would go past the end of the memory slot, do not perform the read
return false;
}
}
bool ExtMemSlot::zeroAdvance(size_t numBytes)
{
if (!m_valid) { return false; }
if (m_currentWrPosition + numBytes-1 <= m_end) {
// entire block fits in memory slot without wrapping
m_spi->zero(m_currentWrPosition, numBytes); // cast audio data to uint.
m_currentWrPosition += numBytes;
} else {
// this write will wrap the memory slot
size_t wrBytes = m_end - m_currentWrPosition + 1;
m_spi->zero(m_currentWrPosition, wrBytes);
size_t remainingBytes = numBytes - wrBytes; // calculate the remaining bytes
m_spi->zero(m_start, remainingBytes); // write remaining bytes are start
m_currentWrPosition = m_start + remainingBytes;
}
return true;
}
bool ExtMemSlot::writeAdvance(uint8_t data)
{
if (!m_valid) { return false; }
m_spi->write(m_currentWrPosition, static_cast<uint8_t>(data));
if (m_currentWrPosition < m_end-1) {
m_currentWrPosition++; // wrote two bytes
} else {
m_currentWrPosition = m_start;
}
return true;
}
bool ExtMemSlot::writeAdvance(uint8_t *src, size_t numBytes)
{
if (!m_valid) { return false; }
if (m_currentWrPosition + numBytes-1 <= m_end) {
// entire block fits in memory slot without wrapping
m_spi->write(m_currentWrPosition, reinterpret_cast<uint8_t*>(src), numBytes); // cast audio data to uint.
m_currentWrPosition += numBytes;
} else {
// this write will wrap the memory slot
size_t wrBytes = m_end - m_currentWrPosition + 1;
m_spi->write(m_currentWrPosition, src, wrBytes);
size_t remainingData = numBytes - wrBytes;
m_spi->write(m_start, src + wrBytes, remainingData); // write remaining bytes are start
m_currentWrPosition = m_start + remainingData;
}
return true;
}
/// Read the next in memory during circular operation
/// @returns the next 8-bit data word in memory
uint8_t ExtMemSlot::readAdvance() {
uint8_t val = m_spi->read(m_currentRdPosition);
if (m_currentRdPosition < m_end-1) {
m_currentRdPosition ++; // position is in bytes and we read two
} else {
m_currentRdPosition = m_start;
}
return val;
}
bool ExtMemSlot::readAdvance(uint8_t *dest, size_t numBytes)
{
if (!m_valid) { return false; }
if (m_currentRdPosition + numBytes-1 <= m_end) {
// entire block fits in memory slot without wrapping
m_spi->read(m_currentRdPosition, dest, numBytes); // cast audio data to uint.
m_currentRdPosition += numBytes;
} else {
// this read will wrap the memory slot
size_t rdBytes = m_end - m_currentRdPosition + 1;
m_spi->read(m_currentRdPosition, dest, rdBytes);
size_t remainingData = numBytes - rdBytes;
m_spi->read(m_start, (dest + rdBytes), remainingData); // write remaining bytes are start
m_currentRdPosition = m_start + remainingData;
}
return true;
}
/////////////////////////////////////////////////////////////////////////
// 16-BIT BASED TRANSFERS
/////////////////////////////////////////////////////////////////////////
bool ExtMemSlot::write16(size_t offsetWords, int16_t *src, size_t numWords)
{
if (!m_valid) { return false; }
size_t writeStart = m_start + sizeof(int16_t)*offsetWords; // 2x because int16 is two bytes per data
size_t numBytes = sizeof(int16_t)*numWords;
if ((writeStart + numBytes-1) <= m_end) {
m_spi->write16(writeStart, reinterpret_cast<uint16_t*>(src), numWords); // cast audio data to uint
return true;
} else {
// this would go past the end of the memory slot, do not perform the write
return false;
}
}
bool ExtMemSlot::zero16(size_t offsetWords, size_t numWords)
{
if (!m_valid) { return false; }

@ -68,7 +68,7 @@ bool ExternalSramManager::requestMemory(ExtMemSlot *slot, size_t sizeBytes, BALi
if (!m_configured) { m_configure(); }
if (m_memConfig[mem].totalAvailable >= sizeBytes) {
Serial.println(String("Configuring a slot for mem ") + mem);
if (Serial) Serial.printf("Configuring mem %d, for size %d, available %d\n\r", (unsigned)mem, sizeBytes, m_memConfig[mem].totalAvailable);
// there is enough available memory for this request
slot->m_start = m_memConfig[mem].nextAvailable;
slot->m_end = slot->m_start + sizeBytes -1;
@ -78,13 +78,16 @@ bool ExternalSramManager::requestMemory(ExtMemSlot *slot, size_t sizeBytes, BALi
if (!m_memConfig[mem].m_spi) {
if (useDma) {
if (Serial) { Serial.printf("Creating S for id %d\n\r", (int)mem);}
m_memConfig[mem].m_spi = new BALibrary::BASpiMemoryDMA(static_cast<BALibrary::SpiDeviceId>(mem));
slot->m_useDma = true;
} else {
if (Serial) { Serial.printf("Creating BASpiMemory for id %d\n\r", (int)mem);}
m_memConfig[mem].m_spi = new BALibrary::BASpiMemory(static_cast<BALibrary::SpiDeviceId>(mem));
slot->m_useDma = false;
}
if (!m_memConfig[mem].m_spi) {
if (Serial) { Serial.printf("Failed to create SPI for id %d\n\r", (int)mem);}
} else {
Serial.println("Calling spi begin()");
m_memConfig[mem].m_spi->begin();

Loading…
Cancel
Save