mirror of
https://github.com/dwhinham/mt32-pi.git
synced 2026-10-26 22:11:05 +00:00
WIP: Pisound TX working, but not at correct clock
TODO: Fix synth routing path
This commit is contained in:
1 parent
e07b48d5eb
commit
c1de5532aa
8 files changed
+115
-36
No files matched your search
@@ -4,7 +4,7 @@
|
|||||||
|
|
||||||
# Valid options: pi3, pi3-64, pi4, pi4-64
|
# Valid options: pi3, pi3-64, pi4, pi4-64
|
||||||
BOARD?=pi3-64
|
BOARD?=pi3-64
|
||||||
HDMI_CONSOLE?=0
|
HDMI_CONSOLE?=1
|
||||||
|
|
||||||
# Serial bootloader config
|
# Serial bootloader config
|
||||||
SERIALPORT?=/dev/ttyUSB0
|
SERIALPORT?=/dev/ttyUSB0
|
||||||
|
|||||||
+2
-2
@@ -29,7 +29,7 @@
|
|||||||
#include <circle/gpiomanager.h>
|
#include <circle/gpiomanager.h>
|
||||||
#include <circle/i2cmaster.h>
|
#include <circle/i2cmaster.h>
|
||||||
#include <circle/sched/scheduler.h>
|
#include <circle/sched/scheduler.h>
|
||||||
#include <circle/spimaster.h>
|
#include <circle/spimasterdma.h>
|
||||||
#include <circle/timer.h>
|
#include <circle/timer.h>
|
||||||
|
|
||||||
#include "config.h"
|
#include "config.h"
|
||||||
@@ -58,7 +58,7 @@ protected:
|
|||||||
FATFS m_SDFileSystem;
|
FATFS m_SDFileSystem;
|
||||||
|
|
||||||
CI2CMaster m_I2CMaster;
|
CI2CMaster m_I2CMaster;
|
||||||
CSPIMaster m_SPIMaster;
|
CSPIMasterDMA m_SPIMaster;
|
||||||
CGPIOManager m_GPIOManager;
|
CGPIOManager m_GPIOManager;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|||||||
+3
-3
@@ -36,7 +36,7 @@
|
|||||||
#include <circle/net/netsubsystem.h>
|
#include <circle/net/netsubsystem.h>
|
||||||
#include <circle/sched/scheduler.h>
|
#include <circle/sched/scheduler.h>
|
||||||
#include <circle/sound/soundbasedevice.h>
|
#include <circle/sound/soundbasedevice.h>
|
||||||
#include <circle/spimaster.h>
|
#include <circle/spimasterdma.h>
|
||||||
#include <circle/timer.h>
|
#include <circle/timer.h>
|
||||||
#include <circle/types.h>
|
#include <circle/types.h>
|
||||||
#include <circle/usb/usbhcidevice.h>
|
#include <circle/usb/usbhcidevice.h>
|
||||||
@@ -69,7 +69,7 @@
|
|||||||
class CMT32Pi : CMultiCoreSupport, CPower, CMIDIParser, CAppleMIDIHandler, CUDPMIDIHandler
|
class CMT32Pi : CMultiCoreSupport, CPower, CMIDIParser, CAppleMIDIHandler, CUDPMIDIHandler
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
CMT32Pi(CI2CMaster* pI2CMaster, CSPIMaster* pSPIMaster, CInterruptSystem* pInterrupt, CGPIOManager* pGPIOManager, CSerialDevice* pSerialDevice, CUSBHCIDevice* pUSBHCI);
|
CMT32Pi(CI2CMaster* pI2CMaster, CSPIMasterDMA* pSPIMaster, CInterruptSystem* pInterrupt, CGPIOManager* pGPIOManager, CSerialDevice* pSerialDevice, CUSBHCIDevice* pUSBHCI);
|
||||||
virtual ~CMT32Pi() override;
|
virtual ~CMT32Pi() override;
|
||||||
|
|
||||||
bool Initialize(bool bSerialMIDIAvailable = true);
|
bool Initialize(bool bSerialMIDIAvailable = true);
|
||||||
@@ -148,7 +148,7 @@ private:
|
|||||||
CActLED* m_pActLED;
|
CActLED* m_pActLED;
|
||||||
|
|
||||||
CI2CMaster* m_pI2CMaster;
|
CI2CMaster* m_pI2CMaster;
|
||||||
CSPIMaster* m_pSPIMaster;
|
CSPIMasterDMA* m_pSPIMaster;
|
||||||
CInterruptSystem* m_pInterrupt;
|
CInterruptSystem* m_pInterrupt;
|
||||||
CGPIOManager* m_pGPIOManager;
|
CGPIOManager* m_pGPIOManager;
|
||||||
CSerialDevice* m_pSerial;
|
CSerialDevice* m_pSerial;
|
||||||
|
|||||||
+11
-5
@@ -25,23 +25,28 @@
|
|||||||
|
|
||||||
#include <circle/gpiomanager.h>
|
#include <circle/gpiomanager.h>
|
||||||
#include <circle/gpiopin.h>
|
#include <circle/gpiopin.h>
|
||||||
#include <circle/spimaster.h>
|
#include <circle/sched/task.h>
|
||||||
|
#include <circle/spimasterdma.h>
|
||||||
|
#include <circle/spinlock.h>
|
||||||
#include <circle/types.h>
|
#include <circle/types.h>
|
||||||
|
|
||||||
#include "ringbuffer.h"
|
#include "ringbuffer.h"
|
||||||
|
|
||||||
class CPisound
|
class CPisound : protected CTask
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
using TMIDIReceiveHandler = void (*)(const u8* pData, size_t nSize);
|
using TMIDIReceiveHandler = void (*)(const u8* pData, size_t nSize);
|
||||||
|
|
||||||
CPisound(CSPIMaster* pSPIMaster, CGPIOManager* pGPIOManager, unsigned nSamplerate);
|
CPisound(CSPIMasterDMA* pSPIMaster, CGPIOManager* pGPIOManager, unsigned nSamplerate);
|
||||||
~CPisound();
|
virtual ~CPisound() override;
|
||||||
|
|
||||||
bool Initialize();
|
bool Initialize();
|
||||||
void RegisterMIDIReceiveHandler(TMIDIReceiveHandler pHandler) { m_pReceiveHandler = pHandler; }
|
void RegisterMIDIReceiveHandler(TMIDIReceiveHandler pHandler) { m_pReceiveHandler = pHandler; }
|
||||||
size_t SendMIDI(const u8* pData, size_t nSize);
|
size_t SendMIDI(const u8* pData, size_t nSize);
|
||||||
|
|
||||||
|
virtual void Run() override;
|
||||||
|
void DoTransfer();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
u16 Transfer16(u16 nValue) const;
|
u16 Transfer16(u16 nValue) const;
|
||||||
size_t ReadBytes(u8* pOutBuffer, size_t nSize) const;
|
size_t ReadBytes(u8* pOutBuffer, size_t nSize) const;
|
||||||
@@ -53,7 +58,8 @@ private:
|
|||||||
static constexpr size_t MaxIDStringLength = 25;
|
static constexpr size_t MaxIDStringLength = 25;
|
||||||
static constexpr size_t MaxVersionStringLength = 6;
|
static constexpr size_t MaxVersionStringLength = 6;
|
||||||
|
|
||||||
CSPIMaster* m_pSPIMaster;
|
CSpinLock m_Lock;
|
||||||
|
CSPIMasterDMA* m_pSPIMaster;
|
||||||
unsigned m_nSamplerate;
|
unsigned m_nSamplerate;
|
||||||
|
|
||||||
CGPIOPin m_SPIReset;
|
CGPIOPin m_SPIReset;
|
||||||
|
|||||||
@@ -42,6 +42,7 @@ CKernel::CKernel(void)
|
|||||||
m_SDFileSystem{},
|
m_SDFileSystem{},
|
||||||
|
|
||||||
m_I2CMaster(1, true),
|
m_I2CMaster(1, true),
|
||||||
|
m_SPIMaster(&mInterrupt),
|
||||||
m_GPIOManager(&mInterrupt),
|
m_GPIOManager(&mInterrupt),
|
||||||
|
|
||||||
m_MT32Pi(&m_I2CMaster, &m_SPIMaster, &mInterrupt, &m_GPIOManager, &m_Serial, &m_USBHCI)
|
m_MT32Pi(&m_I2CMaster, &m_SPIMaster, &mInterrupt, &m_GPIOManager, &m_Serial, &m_USBHCI)
|
||||||
|
|||||||
@@ -41,6 +41,8 @@ void CMIDIParser::ParseMIDIBytes(const u8* pData, size_t nSize, bool bIgnoreNote
|
|||||||
{
|
{
|
||||||
u8 nByte = pData[i];
|
u8 nByte = pData[i];
|
||||||
|
|
||||||
|
//CLogger::Get()->Write(MIDIParserName, LogNotice, "0x%02X", nByte);
|
||||||
|
|
||||||
// System Real-Time message - single byte, handle immediately
|
// System Real-Time message - single byte, handle immediately
|
||||||
// Can appear anywhere in the stream, even in between status/data bytes
|
// Can appear anywhere in the stream, even in between status/data bytes
|
||||||
if (nByte >= 0xF8)
|
if (nByte >= 0xF8)
|
||||||
|
|||||||
+42
-10
@@ -59,7 +59,7 @@ enum class TCustomSysExCommand : u8
|
|||||||
|
|
||||||
CMT32Pi* CMT32Pi::s_pThis = nullptr;
|
CMT32Pi* CMT32Pi::s_pThis = nullptr;
|
||||||
|
|
||||||
CMT32Pi::CMT32Pi(CI2CMaster* pI2CMaster, CSPIMaster* pSPIMaster, CInterruptSystem* pInterrupt, CGPIOManager* pGPIOManager, CSerialDevice* pSerialDevice, CUSBHCIDevice* pUSBHCI)
|
CMT32Pi::CMT32Pi(CI2CMaster* pI2CMaster, CSPIMasterDMA* pSPIMaster, CInterruptSystem* pInterrupt, CGPIOManager* pGPIOManager, CSerialDevice* pSerialDevice, CUSBHCIDevice* pUSBHCI)
|
||||||
: CMultiCoreSupport(CMemorySystem::Get()),
|
: CMultiCoreSupport(CMemorySystem::Get()),
|
||||||
CMIDIParser(),
|
CMIDIParser(),
|
||||||
|
|
||||||
@@ -712,6 +712,29 @@ void CMT32Pi::OnAppleMIDIDisconnect(const CIPAddress* pIPAddress, const char* pN
|
|||||||
LCDLog(TLCDLogType::Notice, "%s disconnected!", pName);
|
LCDLog(TLCDLogType::Notice, "%s disconnected!", pName);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void PrintRouting(const char* pDevice, u8 nRouting)
|
||||||
|
{
|
||||||
|
char Buffer[256];
|
||||||
|
sprintf(Buffer, " - %-10s ->", pDevice);
|
||||||
|
|
||||||
|
if (nRouting == TMIDIRoutingDest::None)
|
||||||
|
{
|
||||||
|
strcat(Buffer, " none");
|
||||||
|
LOGNOTE(Buffer);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (nRouting & TMIDIRoutingDest::Synth) strncat(Buffer, " synth", sizeof(Buffer));
|
||||||
|
if (nRouting & TMIDIRoutingDest::GPIO) strncat(Buffer, " gpio", sizeof(Buffer));
|
||||||
|
if (nRouting & TMIDIRoutingDest::Pisound) strncat(Buffer, " pisound", sizeof(Buffer));
|
||||||
|
if (nRouting & TMIDIRoutingDest::USBMIDI) strncat(Buffer, " usb_midi", sizeof(Buffer));
|
||||||
|
if (nRouting & TMIDIRoutingDest::USBSerial) strncat(Buffer, " usb_serial", sizeof(Buffer));
|
||||||
|
if (nRouting & TMIDIRoutingDest::RTP) strncat(Buffer, " rtp", sizeof(Buffer));
|
||||||
|
if (nRouting & TMIDIRoutingDest::UDP) strncat(Buffer, " udp", sizeof(Buffer));
|
||||||
|
|
||||||
|
LOGNOTE(Buffer);
|
||||||
|
}
|
||||||
|
|
||||||
bool CMT32Pi::ParseCustomSysEx(const u8* pData, size_t nSize)
|
bool CMT32Pi::ParseCustomSysEx(const u8* pData, size_t nSize)
|
||||||
{
|
{
|
||||||
if (nSize < 4)
|
if (nSize < 4)
|
||||||
@@ -745,6 +768,15 @@ bool CMT32Pi::ParseCustomSysEx(const u8* pData, size_t nSize)
|
|||||||
case 4: m_pConfig->MIDIRouteRTP = nRouting; break;
|
case 4: m_pConfig->MIDIRouteRTP = nRouting; break;
|
||||||
case 5: m_pConfig->MIDIRouteUDP = nRouting; break;
|
case 5: m_pConfig->MIDIRouteUDP = nRouting; break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
LOGNOTE("MIDI routing setup:");
|
||||||
|
PrintRouting("gpio", m_pConfig->MIDIRouteGPIO);
|
||||||
|
PrintRouting("usb_midi", m_pConfig->MIDIRouteUSBMIDI);
|
||||||
|
PrintRouting("usb_serial", m_pConfig->MIDIRouteUSBSerial);
|
||||||
|
PrintRouting("pisound", m_pConfig->MIDIRoutePisound);
|
||||||
|
PrintRouting("rtp", m_pConfig->MIDIRouteRTP);
|
||||||
|
PrintRouting("udp", m_pConfig->MIDIRouteUDP);
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1032,7 +1064,7 @@ void CMT32Pi::ProcessMIDIRouting(const TMIDIRouting& Routing, const u8* pData, s
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Send to GPIO UART
|
// Send to GPIO UART
|
||||||
if (Routing & GPIO && m_bSerialMIDIEnabled)
|
if ((Routing & GPIO) && m_bSerialMIDIEnabled)
|
||||||
{
|
{
|
||||||
const int nSendResult = m_pSerial->Write(pData, nSize);
|
const int nSendResult = m_pSerial->Write(pData, nSize);
|
||||||
if (nSendResult < 0 || static_cast<size_t>(nSendResult) != nSize)
|
if (nSendResult < 0 || static_cast<size_t>(nSendResult) != nSize)
|
||||||
@@ -1043,44 +1075,44 @@ void CMT32Pi::ProcessMIDIRouting(const TMIDIRouting& Routing, const u8* pData, s
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Send to Pisound
|
// Send to Pisound
|
||||||
if (Routing & Pisound && m_pPisound)
|
if ((Routing & Pisound) && m_pPisound)
|
||||||
{
|
{
|
||||||
if (m_pPisound->SendMIDI(pData, nSize) != nSize)
|
if (m_pPisound->SendMIDI(pData, nSize) != nSize)
|
||||||
{
|
{
|
||||||
m_pLogger->Write(MT32PiName, LogError, "Pisound MIDI TX error");
|
LOGERR("Pisound MIDI TX error");
|
||||||
LCDLog(TLCDLogType::Error, "Pisound MIDI TX error!");
|
LCDLog(TLCDLogType::Error, "Pisound MIDI TX error!");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Send to USB MIDI
|
// Send to USB MIDI
|
||||||
if (Routing & USBMIDI && m_pUSBMIDIDevice)
|
if ((Routing & USBMIDI) && m_pUSBMIDIDevice)
|
||||||
{
|
{
|
||||||
if (m_pUSBMIDIDevice->SendPlainMIDI(0, pData, nSize) == false)
|
if (m_pUSBMIDIDevice->SendPlainMIDI(0, pData, nSize) == false)
|
||||||
{
|
{
|
||||||
m_pLogger->Write(MT32PiName, LogError, "USB MIDI TX error");
|
LOGERR("USB MIDI TX error");
|
||||||
LCDLog(TLCDLogType::Error, "USB MIDI TX error!");
|
LCDLog(TLCDLogType::Error, "USB MIDI TX error!");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Send to USB serial
|
// Send to USB serial
|
||||||
if (Routing & USBSerial && m_pUSBSerialDevice)
|
if ((Routing & USBSerial) && m_pUSBSerialDevice)
|
||||||
{
|
{
|
||||||
const int nSendResult = m_pUSBSerialDevice->Write(pData, nSize);
|
const int nSendResult = m_pUSBSerialDevice->Write(pData, nSize);
|
||||||
if (nSendResult < 0 || static_cast<size_t>(nSendResult) != nSize)
|
if (nSendResult < 0 || static_cast<size_t>(nSendResult) != nSize)
|
||||||
{
|
{
|
||||||
m_pLogger->Write(MT32PiName, LogError, "USB serial TX error %d (wanted to send %d bytes)", nSendResult, nSize);
|
LOGERR("USB serial TX error %d (wanted to send %d bytes)", nSendResult, nSize);
|
||||||
LCDLog(TLCDLogType::Error, "USB serial TX error!");
|
LCDLog(TLCDLogType::Error, "USB serial TX error!");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Send to AppleMIDI
|
// Send to AppleMIDI
|
||||||
if (Routing & RTP && m_pAppleMIDIParticipant)
|
if ((Routing & RTP) && m_pAppleMIDIParticipant)
|
||||||
{
|
{
|
||||||
// TODO: AppleMIDIParticipant has no transmit functionality
|
// TODO: AppleMIDIParticipant has no transmit functionality
|
||||||
}
|
}
|
||||||
|
|
||||||
// Send to UDP MIDI
|
// Send to UDP MIDI
|
||||||
if (Routing & UDP && m_pUDPMIDIReceiver)
|
if ((Routing & UDP) && m_pUDPMIDIReceiver)
|
||||||
{
|
{
|
||||||
// TODO: UDPMIDIReceiver has no transmit functionality
|
// TODO: UDPMIDIReceiver has no transmit functionality
|
||||||
}
|
}
|
||||||
|
|||||||
+53
-15
@@ -23,6 +23,7 @@
|
|||||||
#include <circle/logger.h>
|
#include <circle/logger.h>
|
||||||
#include <circle/timer.h>
|
#include <circle/timer.h>
|
||||||
#include <circle/util.h>
|
#include <circle/util.h>
|
||||||
|
#include <circle/sched/scheduler.h>
|
||||||
|
|
||||||
#include <cstdio>
|
#include <cstdio>
|
||||||
|
|
||||||
@@ -31,8 +32,8 @@
|
|||||||
LOGMODULE("pisound");
|
LOGMODULE("pisound");
|
||||||
|
|
||||||
constexpr u8 SPIChipSelect = 0;
|
constexpr u8 SPIChipSelect = 0;
|
||||||
constexpr u8 SPIDelayMicroseconds = 10;
|
// FIXME: Linux driver works at 150000Hz, but here we get data corruption hence lower clock speed - investigate
|
||||||
constexpr u32 SPIClockSpeed = 150000;
|
constexpr u32 SPIClockSpeed = 15000;
|
||||||
constexpr u8 SPITransferSize = 4;
|
constexpr u8 SPITransferSize = 4;
|
||||||
|
|
||||||
constexpr u8 GPIOButton = 17;
|
constexpr u8 GPIOButton = 17;
|
||||||
@@ -48,8 +49,10 @@ constexpr u8 GPIOSPIDataAvailable = 25;
|
|||||||
// Based on: https://github.com/raspberrypi/linux/blob/rpi-5.4.y/sound/soc/bcm/pisound.c
|
// Based on: https://github.com/raspberrypi/linux/blob/rpi-5.4.y/sound/soc/bcm/pisound.c
|
||||||
// https://github.com/raspberrypi/linux/blob/rpi-5.4.y/arch/arm/boot/dts/overlays/pisound-overlay.dts
|
// https://github.com/raspberrypi/linux/blob/rpi-5.4.y/arch/arm/boot/dts/overlays/pisound-overlay.dts
|
||||||
|
|
||||||
CPisound::CPisound(CSPIMaster* pSPIMaster, CGPIOManager* pGPIOManager, unsigned nSamplerate)
|
CPisound::CPisound(CSPIMasterDMA* pSPIMaster, CGPIOManager* pGPIOManager, unsigned nSamplerate)
|
||||||
: m_pSPIMaster(pSPIMaster),
|
: CTask(TASK_STACK_SIZE, true),
|
||||||
|
m_Lock(IRQ_LEVEL),
|
||||||
|
m_pSPIMaster(pSPIMaster),
|
||||||
m_nSamplerate(nSamplerate),
|
m_nSamplerate(nSamplerate),
|
||||||
|
|
||||||
m_SPIReset(GPIOSPIReset, TGPIOMode::GPIOModeOutput),
|
m_SPIReset(GPIOSPIReset, TGPIOMode::GPIOModeOutput),
|
||||||
@@ -80,6 +83,8 @@ CPisound::~CPisound()
|
|||||||
m_OversamplingRatio0.SetMode(TGPIOMode::GPIOModeInputPullDown);
|
m_OversamplingRatio0.SetMode(TGPIOMode::GPIOModeInputPullDown);
|
||||||
m_OversamplingRatio1.SetMode(TGPIOMode::GPIOModeInputPullDown);
|
m_OversamplingRatio1.SetMode(TGPIOMode::GPIOModeInputPullDown);
|
||||||
m_OversamplingRatio2.SetMode(TGPIOMode::GPIOModeInputPullDown);
|
m_OversamplingRatio2.SetMode(TGPIOMode::GPIOModeInputPullDown);
|
||||||
|
|
||||||
|
Terminate();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool CPisound::Initialize()
|
bool CPisound::Initialize()
|
||||||
@@ -106,7 +111,6 @@ bool CPisound::Initialize()
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Setup SPI
|
// Setup SPI
|
||||||
m_pSPIMaster->SetCSHoldTime(SPIDelayMicroseconds);
|
|
||||||
m_pSPIMaster->SetClock(SPIClockSpeed);
|
m_pSPIMaster->SetClock(SPIClockSpeed);
|
||||||
|
|
||||||
// Reset the SPI device
|
// Reset the SPI device
|
||||||
@@ -131,15 +135,18 @@ bool CPisound::Initialize()
|
|||||||
LOGNOTE("Firmware version: %s", m_FirmwareVersion);
|
LOGNOTE("Firmware version: %s", m_FirmwareVersion);
|
||||||
LOGNOTE("Hardware version: %s", m_HardwareVersion);
|
LOGNOTE("Hardware version: %s", m_HardwareVersion);
|
||||||
|
|
||||||
|
Start();
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
size_t CPisound::SendMIDI(const u8* pData, size_t nSize)
|
size_t CPisound::SendMIDI(const u8* pData, size_t nSize)
|
||||||
{
|
{
|
||||||
// TODO
|
// Wake up task
|
||||||
m_MIDITxBuffer.Enqueue(pData, nSize);
|
if (IsSuspended())
|
||||||
SPITask();
|
Resume();
|
||||||
return nSize;
|
|
||||||
|
return m_MIDITxBuffer.Enqueue(pData, nSize);
|
||||||
}
|
}
|
||||||
|
|
||||||
u16 CPisound::Transfer16(u16 nTxValue) const
|
u16 CPisound::Transfer16(u16 nTxValue) const
|
||||||
@@ -149,7 +156,7 @@ u16 CPisound::Transfer16(u16 nTxValue) const
|
|||||||
SPITxBuffer[0] = nTxValue >> 8;
|
SPITxBuffer[0] = nTxValue >> 8;
|
||||||
SPITxBuffer[1] = nTxValue & 0xFF;
|
SPITxBuffer[1] = nTxValue & 0xFF;
|
||||||
|
|
||||||
if (m_pSPIMaster->WriteRead(SPIChipSelect, SPITxBuffer, SPIRxBuffer, sizeof(SPIRxBuffer)) < 0)
|
if (m_pSPIMaster->WriteReadSync(SPIChipSelect, SPITxBuffer, SPIRxBuffer, sizeof(SPIRxBuffer)) < 0)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
return (SPIRxBuffer[0] << 8) | SPIRxBuffer[1];
|
return (SPIRxBuffer[0] << 8) | SPIRxBuffer[1];
|
||||||
@@ -246,11 +253,16 @@ void CPisound::SetOSRPins(unsigned bRatio1, unsigned bRatio2, unsigned bRatio3)
|
|||||||
void CPisound::DataAvailableInterruptHandler(void* pUserData)
|
void CPisound::DataAvailableInterruptHandler(void* pUserData)
|
||||||
{
|
{
|
||||||
CPisound* pThis = static_cast<CPisound*>(pUserData);
|
CPisound* pThis = static_cast<CPisound*>(pUserData);
|
||||||
pThis->SPITask();
|
if (pThis->IsSuspended())
|
||||||
|
pThis->Resume();
|
||||||
}
|
}
|
||||||
|
|
||||||
void CPisound::SPITask()
|
void CPisound::DoTransfer()
|
||||||
{
|
{
|
||||||
|
bool bHadData = false;
|
||||||
|
|
||||||
|
m_Lock.Acquire();
|
||||||
|
|
||||||
do
|
do
|
||||||
{
|
{
|
||||||
size_t nMIDIRxBytes = 0;
|
size_t nMIDIRxBytes = 0;
|
||||||
@@ -260,6 +272,8 @@ void CPisound::SPITask()
|
|||||||
|
|
||||||
u8 SPIRxBuffer[SPITransferSize];
|
u8 SPIRxBuffer[SPITransferSize];
|
||||||
u8 SPITxBuffer[SPITransferSize];
|
u8 SPITxBuffer[SPITransferSize];
|
||||||
|
|
||||||
|
bHadData = false;
|
||||||
memset(SPIRxBuffer, 0, sizeof(SPIRxBuffer));
|
memset(SPIRxBuffer, 0, sizeof(SPIRxBuffer));
|
||||||
memset(SPITxBuffer, 0, sizeof(SPITxBuffer));
|
memset(SPITxBuffer, 0, sizeof(SPITxBuffer));
|
||||||
|
|
||||||
@@ -272,15 +286,39 @@ void CPisound::SPITask()
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Extract incoming MIDI bytes from SPI packet
|
// Extract incoming MIDI bytes from SPI packet
|
||||||
m_pSPIMaster->WriteRead(SPIChipSelect, SPITxBuffer, SPIRxBuffer, sizeof(SPIRxBuffer));
|
if (m_pSPIMaster->WriteReadSync(SPIChipSelect, SPITxBuffer, SPIRxBuffer, SPITransferSize) != SPITransferSize)
|
||||||
for (size_t i = 0; i < sizeof(SPIRxBuffer); i += 2)
|
{
|
||||||
|
LOGERR("SPI transfer failed");
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (size_t i = 0; i < SPITransferSize; i += 2)
|
||||||
{
|
{
|
||||||
if (SPIRxBuffer[i])
|
if (SPIRxBuffer[i])
|
||||||
|
{
|
||||||
MIDIRxBuffer[nMIDIRxBytes++] = SPIRxBuffer[i + 1];
|
MIDIRxBuffer[nMIDIRxBytes++] = SPIRxBuffer[i + 1];
|
||||||
|
bHadData = true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Pass MIDI bytes on to handler
|
// Pass MIDI bytes on to handler
|
||||||
if (nMIDIRxBytes && m_pReceiveHandler)
|
if (nMIDIRxBytes && m_pReceiveHandler)
|
||||||
m_pReceiveHandler(MIDIRxBuffer, nMIDIRxBytes);
|
m_pReceiveHandler(MIDIRxBuffer, nMIDIRxBytes);
|
||||||
} while (m_DataAvailable.Read() == HIGH || !m_MIDITxBuffer.IsEmpty());
|
} while (bHadData || !m_MIDITxBuffer.IsEmpty() || m_DataAvailable.Read() == HIGH);
|
||||||
|
|
||||||
|
m_Lock.Release();
|
||||||
|
}
|
||||||
|
|
||||||
|
void CPisound::Run()
|
||||||
|
{
|
||||||
|
CScheduler* const pScheduler = CScheduler::Get();
|
||||||
|
|
||||||
|
while (true)
|
||||||
|
{
|
||||||
|
DoTransfer();
|
||||||
|
Suspend();
|
||||||
|
|
||||||
|
// Allow other tasks to run
|
||||||
|
pScheduler->Yield();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
Reference in new issue
Block a user