From 129e3a3e3b6c1a52d3042652f315724da7477122 Mon Sep 17 00:00:00 2001 From: Blackaddr Date: Sat, 26 Nov 2022 11:52:03 -0500 Subject: [PATCH] w.i.p --- src/BAHardware.h | 35 ++++++- src/LibMemoryManagement.h | 52 +++++++++- src/common/BAHardware.cpp | 74 +++++++++++--- src/common/ExtMemSlot.cpp | 150 +++++++++++++++++++++++++++-- src/common/ExternalSramManager.cpp | 5 +- 5 files changed, 291 insertions(+), 25 deletions(-) diff --git a/src/BAHardware.h b/src/BAHardware.h index 1fdf93f..89b74b7 100644 --- a/src/BAHardware.h +++ b/src/BAHardware.h @@ -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 diff --git a/src/LibMemoryManagement.h b/src/LibMemoryManagement.h index 4d049b3..33ff7df 100644 --- a/src/LibMemoryManagement.h +++ b/src/LibMemoryManagement.h @@ -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. diff --git a/src/common/BAHardware.cpp b/src/common/BAHardware.cpp index 0aea37d..4fece7f 100644 --- a/src/common/BAHardware.cpp +++ b/src/common/BAHardware.cpp @@ -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 } diff --git a/src/common/ExtMemSlot.cpp b/src/common/ExtMemSlot.cpp index 1574126..d04f054 100644 --- a/src/common/ExtMemSlot.cpp +++ b/src/common/ExtMemSlot.cpp @@ -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(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(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(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(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; } diff --git a/src/common/ExternalSramManager.cpp b/src/common/ExternalSramManager.cpp index 377f646..c4713ab 100644 --- a/src/common/ExternalSramManager.cpp +++ b/src/common/ExternalSramManager.cpp @@ -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(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(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();