Integrate 3ds_pxi and 3ds_sm
This commit is contained in:
139
sysmodules/pxi/source/PXI.c
Normal file
139
sysmodules/pxi/source/PXI.c
Normal file
@@ -0,0 +1,139 @@
|
||||
/*
|
||||
PXI.c:
|
||||
PXI I/O functions.
|
||||
|
||||
(c) TuxSH, 2016-2017
|
||||
This is part of 3ds_pxi, which is licensed under the MIT license (see LICENSE for details).
|
||||
*/
|
||||
|
||||
#include "PXI.h"
|
||||
|
||||
void PXIReset(void)
|
||||
{
|
||||
REG_PXI_SYNC = 0;
|
||||
REG_PXI_CNT = CNT_CLEAR_SEND_FIFO;
|
||||
|
||||
for(u32 i = 0; i < 16; i += 2)
|
||||
{
|
||||
REG_PXI_RECV;
|
||||
REG_PXI_RECV;
|
||||
}
|
||||
|
||||
REG_PXI_CNT = 0;
|
||||
REG_PXI_CNT = CNT_ENABLE_FIFOs | CNT_ACKNOWLEDGE_FIFO_ERROR | CNT_CLEAR_SEND_FIFO;
|
||||
}
|
||||
|
||||
void PXITriggerSync9IRQ(void)
|
||||
{
|
||||
REG_PXI_INTERRUPT_CNT |= SYNC_TRIGGER_SYNC9_IRQ;
|
||||
}
|
||||
|
||||
bool PXIIsSendFIFOFull(void)
|
||||
{
|
||||
return (REG_PXI_CNT & CNT_SEND_FIFO_FULL_STATUS) != 0;
|
||||
}
|
||||
|
||||
void PXISendByte(u8 byte)
|
||||
{
|
||||
REG_PXI_BYTE_SENT_TO_REMOTE = byte;
|
||||
}
|
||||
|
||||
void PXISendWord(u32 word)
|
||||
{
|
||||
while(REG_PXI_CNT & CNT_SEND_FIFO_FULL_STATUS);
|
||||
REG_PXI_SEND = word;
|
||||
}
|
||||
|
||||
void PXISendBuffer(const u32 *buffer, u32 nbWords)
|
||||
{
|
||||
for(; nbWords > 0; nbWords--)
|
||||
{
|
||||
while(REG_PXI_CNT & CNT_SEND_FIFO_FULL_STATUS);
|
||||
REG_PXI_SEND = *buffer++;
|
||||
}
|
||||
}
|
||||
|
||||
bool PXIIsReceiveFIFOEmpty(void)
|
||||
{
|
||||
return (REG_PXI_CNT & CNT_RECEIVE_FIFO_EMPTY_STATUS) != 0;
|
||||
}
|
||||
|
||||
u8 PXIReceiveByte(void)
|
||||
{
|
||||
return REG_PXI_BYTE_RECEIVED_FROM_REMOTE;
|
||||
}
|
||||
|
||||
u32 PXIReceiveWord(void)
|
||||
{
|
||||
while(REG_PXI_CNT & CNT_RECEIVE_FIFO_EMPTY_STATUS);
|
||||
return REG_PXI_RECV;
|
||||
}
|
||||
|
||||
void PXIReceiveBuffer(u32 *buffer, u32 nbWords)
|
||||
{
|
||||
for(; nbWords > 0; nbWords--)
|
||||
{
|
||||
while(REG_PXI_CNT & CNT_RECEIVE_FIFO_EMPTY_STATUS);
|
||||
*buffer++ = REG_PXI_RECV;
|
||||
}
|
||||
}
|
||||
|
||||
Result bindPXIInterrupts(Handle *syncInterrupt, Handle *receiveFIFONotEmptyInterrupt, Handle *sendFIFOEmptyInterrupt)
|
||||
{
|
||||
Result res = 0;
|
||||
u32 mask = CNT_ENABLE_FIFOs | CNT_ENABLE_RECEIVE_FIFO_NOT_EMPTY_IRQ | CNT_ENABLE_SEND_FIFO_EMPTY_IRQ;
|
||||
if(receiveFIFONotEmptyInterrupt != NULL)
|
||||
{
|
||||
res = svcBindInterrupt(0x53, *receiveFIFONotEmptyInterrupt, 0, false);
|
||||
if(R_FAILED(res))
|
||||
{
|
||||
unbindPXIInterrupts(syncInterrupt, receiveFIFONotEmptyInterrupt, sendFIFOEmptyInterrupt);
|
||||
return res;
|
||||
}
|
||||
REG_PXI_CNT = (REG_PXI_CNT & mask) | CNT_ENABLE_RECEIVE_FIFO_NOT_EMPTY_IRQ;
|
||||
}
|
||||
|
||||
if(sendFIFOEmptyInterrupt != NULL)
|
||||
{
|
||||
res = svcBindInterrupt(0x52, *sendFIFOEmptyInterrupt, 0, false);
|
||||
if(R_FAILED(res))
|
||||
{
|
||||
unbindPXIInterrupts(syncInterrupt, receiveFIFONotEmptyInterrupt, sendFIFOEmptyInterrupt);
|
||||
return res;
|
||||
}
|
||||
REG_PXI_CNT = (REG_PXI_CNT & mask) | CNT_ENABLE_SEND_FIFO_EMPTY_IRQ;
|
||||
}
|
||||
|
||||
if(syncInterrupt != NULL)
|
||||
{
|
||||
res = svcBindInterrupt(0x50, *syncInterrupt, 0, false);
|
||||
if(R_FAILED(res))
|
||||
{
|
||||
unbindPXIInterrupts(syncInterrupt, receiveFIFONotEmptyInterrupt, sendFIFOEmptyInterrupt);
|
||||
return res;
|
||||
}
|
||||
REG_PXI_INTERRUPT_CNT |= SYNC_ENABLE_SYNC11_IRQ;
|
||||
}
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
void unbindPXIInterrupts(Handle *syncInterrupt, Handle *receiveFIFONotEmptyInterrupt, Handle *sendFIFOEmptyInterrupt)
|
||||
{
|
||||
if(receiveFIFONotEmptyInterrupt != NULL)
|
||||
{
|
||||
REG_PXI_CNT &= CNT_ENABLE_FIFOs | CNT_ENABLE_SEND_FIFO_EMPTY_IRQ;
|
||||
svcUnbindInterrupt(0x53, *receiveFIFONotEmptyInterrupt);
|
||||
}
|
||||
|
||||
if(sendFIFOEmptyInterrupt != NULL)
|
||||
{
|
||||
REG_PXI_CNT &= CNT_ENABLE_FIFOs | CNT_ENABLE_RECEIVE_FIFO_NOT_EMPTY_IRQ;
|
||||
svcUnbindInterrupt(0x52, *sendFIFOEmptyInterrupt);
|
||||
}
|
||||
if(syncInterrupt != NULL)
|
||||
{
|
||||
REG_PXI_INTERRUPT_CNT &= ~SYNC_ENABLE_SYNC11_IRQ;
|
||||
svcUnbindInterrupt(0x50, *syncInterrupt);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user