mirror of
https://github.com/dwhinham/mt32-pi.git
synced 2026-10-26 22:11:05 +00:00
WIP: Pisound MIDI send
This commit is contained in:
1 parent
4eb35822aa
commit
e07b48d5eb
4 files changed
+69
-26
No files matched your search
@@ -28,6 +28,8 @@
|
||||
#include <circle/spimaster.h>
|
||||
#include <circle/types.h>
|
||||
|
||||
#include "ringbuffer.h"
|
||||
|
||||
class CPisound
|
||||
{
|
||||
public:
|
||||
@@ -38,12 +40,14 @@ public:
|
||||
|
||||
bool Initialize();
|
||||
void RegisterMIDIReceiveHandler(TMIDIReceiveHandler pHandler) { m_pReceiveHandler = pHandler; }
|
||||
size_t SendMIDI(const u8* pData, size_t nSize);
|
||||
|
||||
private:
|
||||
u16 Transfer16(u16 nValue) const;
|
||||
size_t ReadBytes(u8* pOutBuffer, size_t nSize) const;
|
||||
bool ReadInfo();
|
||||
void SetOSRPins(unsigned bRatio1, unsigned bRatio2, unsigned bRatio3);
|
||||
void SPITask();
|
||||
|
||||
static constexpr size_t MaxSerialNumberStringLength = 11;
|
||||
static constexpr size_t MaxIDStringLength = 25;
|
||||
@@ -67,6 +71,8 @@ private:
|
||||
char m_FirmwareVersion[MaxVersionStringLength];
|
||||
char m_HardwareVersion[MaxVersionStringLength];
|
||||
|
||||
CRingBuffer<u8, 64> m_MIDITxBuffer;
|
||||
|
||||
static void DataAvailableInterruptHandler(void* pUserData);
|
||||
};
|
||||
|
||||
|
||||
@@ -97,6 +97,16 @@ public:
|
||||
return nDequeued;
|
||||
}
|
||||
|
||||
size_t Count() const
|
||||
{
|
||||
return (N - m_nOutPtr + m_nInPtr) & BufferMask;
|
||||
}
|
||||
|
||||
bool IsEmpty() const
|
||||
{
|
||||
return m_nInPtr == m_nOutPtr;
|
||||
}
|
||||
|
||||
private:
|
||||
static_assert(Utility::IsPowerOfTwo(N), "Ring buffer size must be a power of 2");
|
||||
|
||||
|
||||
+5
-1
@@ -1045,7 +1045,11 @@ void CMT32Pi::ProcessMIDIRouting(const TMIDIRouting& Routing, const u8* pData, s
|
||||
// Send to Pisound
|
||||
if (Routing & Pisound && m_pPisound)
|
||||
{
|
||||
// TODO: Pisound driver has no transmit functionality
|
||||
if (m_pPisound->SendMIDI(pData, nSize) != nSize)
|
||||
{
|
||||
m_pLogger->Write(MT32PiName, LogError, "Pisound MIDI TX error");
|
||||
LCDLog(TLCDLogType::Error, "Pisound MIDI TX error!");
|
||||
}
|
||||
}
|
||||
|
||||
// Send to USB MIDI
|
||||
|
||||
+48
-25
@@ -134,17 +134,25 @@ bool CPisound::Initialize()
|
||||
return true;
|
||||
}
|
||||
|
||||
size_t CPisound::SendMIDI(const u8* pData, size_t nSize)
|
||||
{
|
||||
// TODO
|
||||
m_MIDITxBuffer.Enqueue(pData, nSize);
|
||||
SPITask();
|
||||
return nSize;
|
||||
}
|
||||
|
||||
u16 CPisound::Transfer16(u16 nTxValue) const
|
||||
{
|
||||
u8 RxBuffer[2];
|
||||
u8 TxBuffer[2];
|
||||
TxBuffer[0] = nTxValue >> 8;
|
||||
TxBuffer[1] = nTxValue & 0xFF;
|
||||
u8 SPIRxBuffer[2];
|
||||
u8 SPITxBuffer[2];
|
||||
SPITxBuffer[0] = nTxValue >> 8;
|
||||
SPITxBuffer[1] = nTxValue & 0xFF;
|
||||
|
||||
if (m_pSPIMaster->WriteRead(SPIChipSelect, TxBuffer, RxBuffer, sizeof(RxBuffer)) < 0)
|
||||
if (m_pSPIMaster->WriteRead(SPIChipSelect, SPITxBuffer, SPIRxBuffer, sizeof(SPIRxBuffer)) < 0)
|
||||
return 0;
|
||||
|
||||
return (RxBuffer[0] << 8) | RxBuffer[1];
|
||||
return (SPIRxBuffer[0] << 8) | SPIRxBuffer[1];
|
||||
}
|
||||
|
||||
size_t CPisound::ReadBytes(u8* pOutBuffer, size_t nSize) const
|
||||
@@ -179,12 +187,12 @@ bool CPisound::ReadInfo()
|
||||
return false;
|
||||
|
||||
u8 nCount = nRx & 0xFF;
|
||||
u8 RxBuffer[256 + 1];
|
||||
u8 SPIRxBuffer[256 + 1];
|
||||
|
||||
for (u8 i = 0; i < nCount; ++i)
|
||||
{
|
||||
memset(RxBuffer, 0, sizeof(RxBuffer));
|
||||
size_t nResult = ReadBytes(RxBuffer, sizeof(RxBuffer) - 1);
|
||||
memset(SPIRxBuffer, 0, sizeof(SPIRxBuffer));
|
||||
size_t nResult = ReadBytes(SPIRxBuffer, sizeof(SPIRxBuffer) - 1);
|
||||
if (!nResult)
|
||||
return false;
|
||||
|
||||
@@ -195,14 +203,14 @@ bool CPisound::ReadInfo()
|
||||
if (nResult != 2)
|
||||
return false;
|
||||
|
||||
snprintf(i == 0 ? m_FirmwareVersion : m_HardwareVersion, MaxVersionStringLength, "%x.%02x", RxBuffer[0], RxBuffer[1]);
|
||||
snprintf(i == 0 ? m_FirmwareVersion : m_HardwareVersion, MaxVersionStringLength, "%x.%02x", SPIRxBuffer[0], SPIRxBuffer[1]);
|
||||
break;
|
||||
|
||||
case 1:
|
||||
if (nResult >= sizeof(m_SerialNumber))
|
||||
return false;
|
||||
|
||||
memcpy(m_SerialNumber, RxBuffer, sizeof(m_SerialNumber));
|
||||
memcpy(m_SerialNumber, SPIRxBuffer, sizeof(m_SerialNumber));
|
||||
break;
|
||||
|
||||
case 2:
|
||||
@@ -212,7 +220,7 @@ bool CPisound::ReadInfo()
|
||||
|
||||
char* pCurrentChar = m_ID;
|
||||
for (size_t j = 0; j < nResult; ++j)
|
||||
pCurrentChar += sprintf(pCurrentChar, "%02x", RxBuffer[j]);
|
||||
pCurrentChar += sprintf(pCurrentChar, "%02x", SPIRxBuffer[j]);
|
||||
*pCurrentChar = '\0';
|
||||
|
||||
break;
|
||||
@@ -238,26 +246,41 @@ void CPisound::SetOSRPins(unsigned bRatio1, unsigned bRatio2, unsigned bRatio3)
|
||||
void CPisound::DataAvailableInterruptHandler(void* pUserData)
|
||||
{
|
||||
CPisound* pThis = static_cast<CPisound*>(pUserData);
|
||||
assert(pThis && pThis->m_pReceiveHandler);
|
||||
pThis->SPITask();
|
||||
}
|
||||
|
||||
void CPisound::SPITask()
|
||||
{
|
||||
do
|
||||
{
|
||||
size_t nMIDIBytes = 0;
|
||||
u8 MIDIBuffer[SPITransferSize / 2];
|
||||
size_t nMIDIRxBytes = 0;
|
||||
size_t nMIDITxBytes = 0;
|
||||
u8 MIDIRxBuffer[SPITransferSize / 2];
|
||||
u8 MIDITxBuffer[SPITransferSize / 2];
|
||||
|
||||
u8 RxBuffer[SPITransferSize];
|
||||
memset(RxBuffer, 0, sizeof(RxBuffer));
|
||||
u8 SPIRxBuffer[SPITransferSize];
|
||||
u8 SPITxBuffer[SPITransferSize];
|
||||
memset(SPIRxBuffer, 0, sizeof(SPIRxBuffer));
|
||||
memset(SPITxBuffer, 0, sizeof(SPITxBuffer));
|
||||
|
||||
// Extract MIDI bytes from SPI packet
|
||||
pThis->m_pSPIMaster->Read(SPIChipSelect, RxBuffer, sizeof(RxBuffer));
|
||||
for (size_t i = 0; i < sizeof(RxBuffer); i += 2)
|
||||
// Prepare outgoing MIDI SPI packet
|
||||
nMIDITxBytes = m_MIDITxBuffer.Dequeue(MIDITxBuffer, sizeof(MIDITxBuffer));
|
||||
for (size_t i = 0; i < nMIDITxBytes; ++i)
|
||||
{
|
||||
if (RxBuffer[i])
|
||||
MIDIBuffer[nMIDIBytes++] = RxBuffer[i + 1];
|
||||
SPITxBuffer[i * 2] = 0x0F;
|
||||
SPITxBuffer[i * 2 + 1] = MIDITxBuffer[i];
|
||||
}
|
||||
|
||||
// Extract incoming MIDI bytes from SPI packet
|
||||
m_pSPIMaster->WriteRead(SPIChipSelect, SPITxBuffer, SPIRxBuffer, sizeof(SPIRxBuffer));
|
||||
for (size_t i = 0; i < sizeof(SPIRxBuffer); i += 2)
|
||||
{
|
||||
if (SPIRxBuffer[i])
|
||||
MIDIRxBuffer[nMIDIRxBytes++] = SPIRxBuffer[i + 1];
|
||||
}
|
||||
|
||||
// Pass MIDI bytes on to handler
|
||||
if (nMIDIBytes)
|
||||
pThis->m_pReceiveHandler(MIDIBuffer, nMIDIBytes);
|
||||
} while (pThis->m_DataAvailable.Read() == HIGH);
|
||||
if (nMIDIRxBytes && m_pReceiveHandler)
|
||||
m_pReceiveHandler(MIDIRxBuffer, nMIDIRxBytes);
|
||||
} while (m_DataAvailable.Read() == HIGH || !m_MIDITxBuffer.IsEmpty());
|
||||
}
|
||||
Reference in new issue
Block a user