diff --git a/src/BAGpio.h b/src/BAGpio.h index f7766af..b038c3d 100644 --- a/src/BAGpio.h +++ b/src/BAGpio.h @@ -67,6 +67,11 @@ public: /// @returns the new stage of the user LED. int toggleLed(); + /// Convert the GPIO enum to the underlying logical pin number + /// @param gpio the enum value to convert + /// @returns the logical pin number for the GPIO + uint8_t enumToPinNumber(GPIO gpio); + private: uint8_t m_ledState; }; diff --git a/src/common/AudioDelay.cpp b/src/common/AudioDelay.cpp index 69a6522..b2e26b7 100644 --- a/src/common/AudioDelay.cpp +++ b/src/common/AudioDelay.cpp @@ -87,7 +87,6 @@ audio_block_t* AudioDelay::addBlock(audio_block_t *block) setSpiDmaCopyBuffer(); #endif - // this causes pops m_slot->writeAdvance16(block->data, AUDIO_BLOCK_SAMPLES); } blockToRelease = block; @@ -115,7 +114,10 @@ size_t AudioDelay::getMaxDelaySamples() bool AudioDelay::getSamples(audio_block_t *dest, size_t offsetSamples, size_t numSamples) { - return m_getSamples(dest->data, offsetSamples, numSamples); + if (!dest) { return false; } + else { + return m_getSamples(dest->data, offsetSamples, numSamples); + } } bool AudioDelay::getSamples(int16_t *dest, size_t offsetSamples, size_t numSamples) @@ -221,6 +223,7 @@ bool AudioDelay::interpolateDelay(int16_t *extendedSourceBuffer, int16_t *destBu bool AudioDelay::setSpiDmaCopyBuffer(void) { bool returnValue = false; + if (m_slot->isUseDma()) { // For DMA use on T4.0 we need this kluge BASpiMemoryDMA * spiDma = static_cast(m_slot->getSpiMemoryHandle()); diff --git a/src/common/ExtMemSlot.cpp b/src/common/ExtMemSlot.cpp index c857cbe..1574126 100644 --- a/src/common/ExtMemSlot.cpp +++ b/src/common/ExtMemSlot.cpp @@ -144,11 +144,17 @@ bool ExtMemSlot::writeAdvance16(int16_t *src, size_t numWords) // this write will wrap the memory slot size_t wrBytes = m_end - m_currentWrPosition + 1; size_t wrDataNum = wrBytes >> 1; // divide by two to get the number of data + m_spi->write16(m_currentWrPosition, reinterpret_cast(src), wrDataNum); size_t remainingData = numWords - wrDataNum; + m_spi->write16(m_start, reinterpret_cast(src + wrDataNum), remainingData); // write remaining bytes are start m_currentWrPosition = m_start + (remainingData*sizeof(int16_t)); } + + // If a write transaction landed exactly on the end of the memory, the next position must be + // manually put back to the start + if (m_currentWrPosition > m_end) { m_currentWrPosition = m_start; } return true; } diff --git a/src/effects/AudioEffectAnalogDelay.cpp b/src/effects/AudioEffectAnalogDelay.cpp index a32fc8b..b9ef77a 100644 --- a/src/effects/AudioEffectAnalogDelay.cpp +++ b/src/effects/AudioEffectAnalogDelay.cpp @@ -77,50 +77,52 @@ void AudioEffectAnalogDelay::setFilter(Filter filter) void AudioEffectAnalogDelay::update(void) { - audio_block_t *inputAudioBlock = receiveReadOnly(); // get the next block of input samples - // Check is block is disabled - if (m_enable == false) { - // do not transmit or process any audio, return as quickly as possible. - if (inputAudioBlock) release(inputAudioBlock); - - // release all held memory resources - if (m_previousBlock) { - release(m_previousBlock); m_previousBlock = nullptr; - } - if (!m_externalMemory) { - // when using internal memory we have to release all references in the ring buffer - while (m_memory->getRingBuffer()->size() > 0) { - audio_block_t *releaseBlock = m_memory->getRingBuffer()->front(); - m_memory->getRingBuffer()->pop_front(); - if (releaseBlock) release(releaseBlock); - } - } - return; - } - - // Check is block is bypassed, if so either transmit input directly or create silence - if (m_bypass == true) { - // transmit the input directly - if (!inputAudioBlock) { - // create silence - inputAudioBlock = allocate(); - if (!inputAudioBlock) { return; } // failed to allocate - else { - clearAudioBlock(inputAudioBlock); - } - } - transmit(inputAudioBlock, 0); - release(inputAudioBlock); - return; - } + // Check is block is disabled + if (m_enable == false) { + // release all held memory resources + if (m_previousBlock) { + release(m_previousBlock); m_previousBlock = nullptr; + } + if (!m_externalMemory) { + // when using internal memory we have to release all references in the ring buffer + while (m_memory->getRingBuffer()->size() > 0) { + audio_block_t *releaseBlock = m_memory->getRingBuffer()->front(); + m_memory->getRingBuffer()->pop_front(); + if (releaseBlock) release(releaseBlock); + } + } + return; + } + + audio_block_t *inputAudioBlock = receiveReadOnly(); // get the next block of input samples + + // Check is block is bypassed, if so either transmit input directly or create silence + if ((m_bypass == true) || (!inputAudioBlock)) { + // transmit the input directly + if (!inputAudioBlock) { + // create silence + inputAudioBlock = allocate(); + if (!inputAudioBlock) { return; } // failed to allocate + else { + clearAudioBlock(inputAudioBlock); + } + } + transmit(inputAudioBlock, 0); + release(inputAudioBlock); + return; + } // Otherwise perform normal processing // In order to make use of the SPI DMA, we need to request the read from memory first, // then do other processing while it fills in the back. audio_block_t *blockToOutput = nullptr; // this will hold the output audio blockToOutput = allocate(); - if (!blockToOutput) return; // skip this update cycle due to failure + if (!blockToOutput) { + transmit(inputAudioBlock, 0); + release(inputAudioBlock); + return; // skip this update cycle due to failure + } // get the data. If using external memory with DMA, this won't be filled until // later. diff --git a/src/effects/AudioEffectTremolo.cpp b/src/effects/AudioEffectTremolo.cpp index 0bb4d67..212f3c3 100644 --- a/src/effects/AudioEffectTremolo.cpp +++ b/src/effects/AudioEffectTremolo.cpp @@ -28,17 +28,16 @@ AudioEffectTremolo::~AudioEffectTremolo() void AudioEffectTremolo::update(void) { - audio_block_t *inputAudioBlock = receiveWritable(); // get the next block of input samples + // Check is block is disabled + if (m_enable == false) { + // do not transmit or process any audio, return as quickly as possible. + return; + } - // Check is block is disabled - if (m_enable == false) { - // do not transmit or process any audio, return as quickly as possible. - if (inputAudioBlock) release(inputAudioBlock); - return; - } + audio_block_t *inputAudioBlock = receiveWritable(); // get the next block of input samples // Check is block is bypassed, if so either transmit input directly or create silence - if (m_bypass == true) { + if ((m_bypass == true) || (!inputAudioBlock)) { // transmit the input directly if (!inputAudioBlock) { // create silence diff --git a/src/peripherals/BAGpio.cpp b/src/peripherals/BAGpio.cpp index e2d3c79..6f15e0e 100644 --- a/src/peripherals/BAGpio.cpp +++ b/src/peripherals/BAGpio.cpp @@ -26,18 +26,18 @@ namespace BALibrary { BAGpio::BAGpio() { // Set all GPIOs to input - pinMode(static_cast(GPIO::GPIO0), INPUT); - pinMode(static_cast(GPIO::GPIO1), INPUT); - pinMode(static_cast(GPIO::GPIO2), INPUT); - pinMode(static_cast(GPIO::GPIO3), INPUT); - pinMode(static_cast(GPIO::GPIO4), INPUT); - pinMode(static_cast(GPIO::GPIO5), INPUT); - pinMode(static_cast(GPIO::GPIO6), INPUT); - pinMode(static_cast(GPIO::GPIO7), INPUT); - pinMode(static_cast(GPIO::TP1), INPUT); - pinMode(static_cast(GPIO::TP2), INPUT); + pinMode(GPIO0, INPUT); + pinMode(GPIO1, INPUT); + pinMode(GPIO2, INPUT); + pinMode(GPIO3, INPUT); + pinMode(GPIO4, INPUT); + pinMode(GPIO5, INPUT); + pinMode(GPIO6, INPUT); + pinMode(GPIO7, INPUT); + pinMode(TP1, INPUT); + pinMode(TP2, INPUT); - // Set the LED ot ouput + // Set the LED to ouput pinMode(USR_LED_ID, OUTPUT); clearLed(); // turn off the LED @@ -49,21 +49,21 @@ BAGpio::~BAGpio() void BAGpio::setGPIODirection(GPIO gpioId, int direction) { - pinMode(static_cast(gpioId), direction); + pinMode(enumToPinNumber(gpioId), direction); } void BAGpio::setGPIO(GPIO gpioId) { - digitalWrite(static_cast(gpioId), 0x1); + digitalWrite(enumToPinNumber(gpioId), 0x1); } void BAGpio::clearGPIO(GPIO gpioId) { - digitalWrite(static_cast(gpioId), 0); + digitalWrite(enumToPinNumber(gpioId), 0); } int BAGpio::toggleGPIO(GPIO gpioId) { - int data = digitalRead(static_cast(gpioId)); - digitalWrite(static_cast(gpioId), ~data); + int data = digitalRead(enumToPinNumber(gpioId)); + digitalWrite(enumToPinNumber(gpioId), ~data); return ~data; } @@ -84,5 +84,24 @@ int BAGpio::toggleLed() return m_ledState; } +uint8_t enumToPinNumber(GPIO gpio) +{ + uint8_t pinNumber; + switch(gpio) { + case GPIO::GPIO0 : pinNumber = GPIO0; break; + case GPIO::GPIO1 : pinNumber = GPIO1; break; + case GPIO::GPIO2 : pinNumber = GPIO2; break; + case GPIO::GPIO3 : pinNumber = GPIO3; break; + case GPIO::GPIO4 : pinNumber = GPIO4; break; + case GPIO::GPIO5 : pinNumber = GPIO5; break; + case GPIO::GPIO6 : pinNumber = GPIO6; break; + case GPIO::GPIO7 : pinNumber = GPIO7; break; + case GPIO::TP1 : pinNumber = TP1; break; + case GPIO::TP2 : pinNumber = TP2; break; + default : pinNumber = 0; break; + } + return pinNumber; +} + } /* namespace BALibrary */ diff --git a/src/peripherals/BAPhysicalControls.cpp b/src/peripherals/BAPhysicalControls.cpp index e479ad3..0a81c9d 100644 --- a/src/peripherals/BAPhysicalControls.cpp +++ b/src/peripherals/BAPhysicalControls.cpp @@ -319,6 +319,9 @@ void Potentiometer::setChangeThreshold(float changeThreshold) Potentiometer::Calib Potentiometer::calibrate(uint8_t pin) { Calib calib; + // Flush the serial port input buffer + while (Serial.available() > 0) {} + Serial.print("Calibration pin "); Serial.println(pin); Serial.println("Move the pot fully counter-clockwise to the minimum setting and press any key then ENTER"); while (true) { diff --git a/src/peripherals/BASpiMemory.cpp b/src/peripherals/BASpiMemory.cpp index 90ed46d..1c9e702 100644 --- a/src/peripherals/BASpiMemory.cpp +++ b/src/peripherals/BASpiMemory.cpp @@ -24,19 +24,19 @@ namespace BALibrary { -// MEM0 Settings -constexpr int SPI_CS_MEM0 = SPI0_CS_PIN; -constexpr int SPI_MOSI_MEM0 = SPI0_MOSI_PIN; -constexpr int SPI_MISO_MEM0 = SPI0_MISO_PIN; -constexpr int SPI_SCK_MEM0 = SPI0_SCK_PIN; - -#if defined(SPI1_AVAILABLE) -// MEM1 Settings -constexpr int SPI_CS_MEM1 = SPI1_CS_PIN; -constexpr int SPI_MOSI_MEM1 = SPI1_MOSI_PIN; -constexpr int SPI_MISO_MEM1 = SPI1_MISO_PIN; -constexpr int SPI_SCK_MEM1 = SPI1_SCK_PIN; -#endif +//// MEM0 Settings +//int SPI_CS_MEM0 = SPI0_CS_PIN; +//int SPI_MOSI_MEM0 = SPI0_MOSI_PIN; +//int SPI_MISO_MEM0 = SPI0_MISO_PIN; +//int SPI_SCK_MEM0 = SPI0_SCK_PIN; +// +//#if defined(SPI1_AVAILABLE) +//// MEM1 Settings +//int SPI_CS_MEM1 = SPI1_CS_PIN; +//int SPI_MOSI_MEM1 = SPI1_MOSI_PIN; +//int SPI_MISO_MEM1 = SPI1_MISO_PIN; +//int SPI_SCK_MEM1 = SPI1_SCK_PIN; +//#endif // SPI Constants constexpr int SPI_WRITE_MODE_REG = 0x1; @@ -73,22 +73,22 @@ void BASpiMemory::begin() { switch (m_memDeviceId) { case SpiDeviceId::SPI_DEVICE0 : - m_csPin = SPI_CS_MEM0; + m_csPin = SPI0_CS_PIN; m_spi = &SPI; - m_spi->setMOSI(SPI_MOSI_MEM0); - m_spi->setMISO(SPI_MISO_MEM0); - m_spi->setSCK(SPI_SCK_MEM0); + m_spi->setMOSI(SPI0_MOSI_PIN); + m_spi->setMISO(SPI0_MISO_PIN); + m_spi->setSCK(SPI0_SCK_PIN); m_spi->begin(); m_dieBoundary = BAHardwareConfig.getSpiMemoryDefinition(MemSelect::MEM0).DIE_BOUNDARY; break; #if defined(__MK64FX512__) || defined(__MK66FX1M0__) case SpiDeviceId::SPI_DEVICE1 : - m_csPin = SPI_CS_MEM1; + m_csPin = SPI1_CS_PIN; m_spi = &SPI1; - m_spi->setMOSI(SPI_MOSI_MEM1); - m_spi->setMISO(SPI_MISO_MEM1); - m_spi->setSCK(SPI_SCK_MEM1); + m_spi->setMOSI(SPI1_MOSI_PIN); + m_spi->setMISO(SPI1_MISO_PIN); + m_spi->setSCK(SPI1_SCK_PIN); m_spi->begin(); m_dieBoundary = BAHardwareConfig.getSpiMemoryDefinition(MemSelect::MEM1).DIE_BOUNDARY; break; @@ -367,17 +367,17 @@ BASpiMemoryDMA::BASpiMemoryDMA(SpiDeviceId memDeviceId) int cs; switch (memDeviceId) { case SpiDeviceId::SPI_DEVICE0 : - cs = SPI_CS_MEM0; + cs = SPI0_CS_PIN; m_cs = new ActiveLowChipSelect(cs, m_settings); break; #if defined(__MK66FX1M0__) case SpiDeviceId::SPI_DEVICE1 : - cs = SPI_CS_MEM1; + cs = SPI1_CS_PIN; m_cs = new ActiveLowChipSelect1(cs, m_settings); break; #endif default : - cs = SPI_CS_MEM0; + cs = SPI0_CS_PIN; } // add 4 bytes to buffer for SPI CMD and 3 bytes of address @@ -393,17 +393,17 @@ BASpiMemoryDMA::BASpiMemoryDMA(SpiDeviceId memDeviceId, uint32_t speedHz) int cs; switch (memDeviceId) { case SpiDeviceId::SPI_DEVICE0 : - cs = SPI_CS_MEM0; + cs = SPI0_CS_PIN; m_cs = new ActiveLowChipSelect(cs, m_settings); break; #if defined(__MK66FX1M0__) case SpiDeviceId::SPI_DEVICE1 : - cs = SPI_CS_MEM1; + cs = SPI1_CS_PIN; m_cs = new ActiveLowChipSelect1(cs, m_settings); break; #endif default : - cs = SPI_CS_MEM0; + cs = SPI0_CS_PIN; } m_txCommandBuffer = new uint8_t[CMD_ADDRESS_SIZE]; @@ -433,11 +433,11 @@ void BASpiMemoryDMA::begin(void) { switch (m_memDeviceId) { case SpiDeviceId::SPI_DEVICE0 : - m_csPin = SPI_CS_MEM0; + m_csPin = SPI0_CS_PIN; m_spi = &SPI; - m_spi->setMOSI(SPI_MOSI_MEM0); - m_spi->setMISO(SPI_MISO_MEM0); - m_spi->setSCK(SPI_SCK_MEM0); + m_spi->setMOSI(SPI0_MOSI_PIN); + m_spi->setMISO(SPI0_MISO_PIN); + m_spi->setSCK(SPI0_SCK_PIN); m_spi->begin(); m_spiDma = new DmaSpiGeneric(); m_dieBoundary = BAHardwareConfig.getSpiMemoryDefinition(MemSelect::MEM0).DIE_BOUNDARY; @@ -445,11 +445,11 @@ void BASpiMemoryDMA::begin(void) #if defined(__MK66FX1M0__) // DMA on SPI1 is only supported on T3.6 case SpiDeviceId::SPI_DEVICE1 : - m_csPin = SPI_CS_MEM1; + m_csPin = SPI1_CS_PIN; m_spi = &SPI1; - m_spi->setMOSI(SPI_MOSI_MEM1); - m_spi->setMISO(SPI_MISO_MEM1); - m_spi->setSCK(SPI_SCK_MEM1); + m_spi->setMOSI(SPI1_MOSI_PIN); + m_spi->setMISO(SPI1_MISO_PIN); + m_spi->setSCK(SPI1_SCK_PIN); m_spi->begin(); m_spiDma = new DmaSpiGeneric(1); m_dieBoundary = BAHardwareConfig.getSpiMemoryDefinition(MemSelect::MEM1).DIE_BOUNDARY; @@ -478,6 +478,8 @@ void BASpiMemoryDMA::write(size_t address, uint8_t *src, size_t numBytes) size_t nextAddress = address; uint8_t *intermediateBuffer = nullptr; + while ( m_txTransfer[1].busy() || m_txTransfer[0].busy()) { yield(); } // wait until not busy + // Check for intermediate buffer use if (m_dmaCopyBufferSize) { // copy to the intermediate buffer; @@ -487,8 +489,6 @@ void BASpiMemoryDMA::write(size_t address, uint8_t *src, size_t numBytes) while (bytesRemaining > 0) { m_txXferCount = m_bytesToXfer(nextAddress, min(bytesRemaining, static_cast(MAX_DMA_XFER_SIZE))); // check for die boundary - - while ( m_txTransfer[1].busy() || m_txTransfer[0].busy()) { yield(); } // wait until not busy m_setSpiCmdAddr(SPI_WRITE_CMD, nextAddress, m_txCommandBuffer); m_txTransfer[1] = DmaSpi::Transfer(m_txCommandBuffer, CMD_ADDRESS_SIZE, nullptr, 0, m_cs, TransferType::NO_END_CS); m_spiDma->registerTransfer(m_txTransfer[1]); @@ -559,14 +559,13 @@ void BASpiMemoryDMA::read(size_t address, uint8_t *dest, size_t numBytes) } while (bytesRemaining > 0) { - m_rxXferCount = m_bytesToXfer(nextAddress, min(bytesRemaining, static_cast(MAX_DMA_XFER_SIZE))); // check for die boundary + while ( m_rxTransfer[1].busy() || m_rxTransfer[0].busy()) { yield(); } + m_rxXferCount = m_bytesToXfer(nextAddress, min(bytesRemaining, static_cast(MAX_DMA_XFER_SIZE))); // check for die boundary m_setSpiCmdAddr(SPI_READ_CMD, nextAddress, m_rxCommandBuffer); - while ( m_rxTransfer[1].busy() || m_rxTransfer[0].busy()) { yield(); } m_rxTransfer[1] = DmaSpi::Transfer(m_rxCommandBuffer, CMD_ADDRESS_SIZE, nullptr, 0, m_cs, TransferType::NO_END_CS); m_spiDma->registerTransfer(m_rxTransfer[1]); - while ( m_rxTransfer[0].busy() || m_rxTransfer[1].busy()) { yield(); } m_rxTransfer[0] = DmaSpi::Transfer(nullptr, m_rxXferCount, destPtr, 0, m_cs, TransferType::NO_START_CS, nullptr, intermediateBuffer); m_spiDma->registerTransfer(m_rxTransfer[0]); @@ -615,7 +614,6 @@ bool BASpiMemoryDMA::setDmaCopyBufferSize(size_t numBytes) m_dmaReadCopyBuffer = (volatile uint8_t*)dma_aligned_malloc(MEM_ALIGNED_ALLOC, numBytes); if (!m_dmaReadCopyBuffer) { - // allocate failed m_dmaCopyBufferSize = 0; return false; }