📄 usbirqfunc.c
字号:
{
if (wLen > MAXLEN_IRQRNDBUF)
{
g_ReplyBuf[5] = 1; // Buffer length error
}
}
else
{
g_ReplyBuf[5] = 2; // Buffer ID error
}
byLen = 6; // Number of byte to be returned
break;
case RCA_DEVIRQ_MOD_SBUF: // Modify scratch buffer (buffer 0)
// We receive the buffer info to USB-uC following format
// ReceiveBuf[0] = RC_IRQ_CONTROL_CMD - command
// ReceiveBuf[1] = RCA_DEVIRQ_MOD_SBUF - sub command
// ReceiveBuf[2] = length of modify-script in byte
// ReceiveBuf[3] = NA
// ReceiveBuf[4+i*2] = Index i in the scratch buffer to be modified
// ReceiveBuf[5+i*2] = Value for index i (i=0...n)
// We reply in format:
// ReplyBuf[0] = RC_IRQ_CONTROL_CMD - command
// ReplyBuf[1] = RCA_DEVIRQ_MOD_SBUF - sub command
// ReplyBuf[2] = length of modify-script in byte
// ReplyBuf[3] = Error code (0=no error)
// Prepare the reply buffer
for (byTmp=0; byTmp<3; byTmp++)
g_ReplyBuf[byTmp] = g_ReceiveBuf[byTmp];
g_ReplyBuf[3] = 0; // No error yet
// Modify the buffer 0 according to the modify-script
for (byTmp=4; byTmp<(g_ReceiveBuf[2]+4); byTmp+=2)
g_byaIrqBuf0[g_ReceiveBuf[byTmp]] = g_ReceiveBuf[byTmp+1];
byLen = 4; // Number of byte to be returned
break;
default: // Do nothing
break;
} // EndSwitch
return(byLen);
} // End UsbIrqControl
BYTE UsbExecScript()
{
// Execute the passed along script command
//I:<cmd><ScriptLength=n><Script data 0><Reply length=m><...><Script data n-1>
//O:<cmd><Return length=m><Return data 0><...><Return data m-1>
UsbLvIrqProcess(&g_ReceiveBuf[3]);
g_ReplyBuf[1] = g_ReceiveBuf[2]; // Data count to be returned (specified by host)
return(2+g_ReplyBuf[1]); // total byte to be send back
} // End UsbExecScript
void ExtRdsIntHandler()
{
// External RDS interrupt handling (invoke when INT4 occurred)
// Somehow, the host wants RDS data in format (after 16 bits):
// RdsBit_0..RdsBit_7 - RdsBit_8..RdsBit_15 (RdsBit_0 is the first received bit)
// In the buffer we have:
// low byte [7:0]: RdsBit[0:7]
// High byte[7:0]: RdsBit[8:15]
// The buffer is filled with 2 bytes each time
BYTE byTmp;
// Check buffer space, no data filling if out of space
if (g_stExtIrq.byF < MAXLEN_IRQRNDBUF)
{
// determine filling low byte/high byte
if (g_byRdsBitCnt < 8)
byTmp = g_stExtIrq.byW; // Fill low byte
else
byTmp = g_stExtIrq.byW + 1; // Fill high byte
// Make room to shift the data in
g_stExtIrq.byBuf[byTmp] <<= 1;
// Read RDS data level and patch it into the buffer
// After first 8 bit, RdsBit_0 becomes DataBit_7
// After next 8 bit, RdsBit_8 becomes DataBit_15
if (EXRDS_PORT & EXRDS_DATA_PIN_BM) // Data is high
g_stExtIrq.byBuf[byTmp] |= 1;
// Advance to next bit
g_byRdsBitCnt++;
// Mark we received 2 bytes when we have enough bits
if (g_byRdsBitCnt == 16)
{
g_stExtIrq.byW += 2; // Adjust the write pointer
g_stExtIrq.byF += 2; // Adjust the byte count
// Wrap the write pointer to 0 when it goes beyond the buffer
if (g_stExtIrq.byW >= MAXLEN_IRQRNDBUF)
g_stExtIrq.byW = 0;
// Reset the bit counter for next time
g_byRdsBitCnt = 0;
}
} // EndIf buffer size check
} // End ExtRdsIntHandler
BYTE CopyRoundRobinBuf(PRNDBUF_ST pStRrBuf)
{
// Copy the data from the specified round robin buffer to the USB-reply buffer.
// The reply buffer is filled until maximal USB packet count reached in followinf format:
// Reply[0]: Command
// Reply[1]: Number of byte in this packet (=n)
// Reply[2]: Data byte 0
// Reply[2+n-1]: data byte n
// The byte filled counter is compensated after the copying
BYTE byLen;
// Determine number of byte to be filled in the reply buffer
if ( pStRrBuf->byF < (USB_REPLY_PACKET_SIZE-2) ) // The 2 first bytes are meant for command and byte count
g_ReplyBuf[1] = pStRrBuf->byF;
else
g_ReplyBuf[1] = (USB_REPLY_PACKET_SIZE-2);
// Copy data
for (byLen=0; byLen<g_ReplyBuf[1]; byLen++)
{
// Copy current byte at read pointer
g_ReplyBuf[2+byLen] = pStRrBuf->byBuf[pStRrBuf->byR];
// Move the read pointer to next byte
pStRrBuf->byR++;
// Wrap the read pointer to the begin if it goes beyond the buffer
if (pStRrBuf->byR == MAXLEN_IRQRNDBUF)
pStRrBuf->byR = 0;
}
// Last step: update the byte count
// The read pointer is laready updated in the copy loop
// This should be done with interrupt free
if (byLen != 0)
pStRrBuf->byF -= byLen;
return(byLen+2); // Return number of byte filled in reply packet
} // End CopyRoundRobinBuf
void UsbLvIrqProcess(PBYTE pbyScript)
{
BYTE byReturn;
// Run the IRQ handling script
while ( pbyScript[0] != ISO_ENDSCRIPT )
{
if ( pbyScript[0] <= SCRIPT_COMMAND_FUNC_MAX )
{
byReturn = ScriptCommandTable[pbyScript[0]](pbyScript[1],pbyScript[2]);
if ( byReturn != SCRIPT_OK )
{
if ( byReturn == SCRIPT_CHK_FAIL )
{
// Skip till next ID
while ( (pbyScript[0] != ISO_ENDSCRIPT) && (pbyScript[0] != ISO_IRQID) )
{
pbyScript+=3;
}
continue;
}
}
}
pbyScript+=3;
}
} // End UsbLvIrqProcess
BYTE ScNOP( BYTE byParm1, BYTE byParm2 )
{
byParm1;
byParm2;
return( SCRIPT_OK );
}
BYTE ScIrqID( BYTE byParm1, BYTE byParm2 )
{
byParm1;
byParm2;
return( SCRIPT_OK );
}
BYTE ScWrite3WD( BYTE byParm1, BYTE byParm2 )
{
UsbWrite3wV3V4(byParm2, byParm1); // Low/High
return( SCRIPT_OK );
}
BYTE ScWrite3WI( BYTE byParm1, BYTE byParm2 )
{
UsbWrite3wV3V4(g_byaIrqBuf0[byParm2], byParm1); // Low/High
return( SCRIPT_OK );
}
BYTE ScRead3W( BYTE byParm1, BYTE byParm2 )
{
g_byaIrqBuf0[byParm2] = UsbRead3wV3V4(byParm1);
return( SCRIPT_OK );
}
BYTE ScChkMaskLow( BYTE byParm1, BYTE byParm2 )
{
if( g_byaIrqBuf0[byParm1] & byParm2 )
return( SCRIPT_CHK_FAIL );
else
return( SCRIPT_OK );
}
BYTE ScChkMaskHigh( BYTE byParm1, BYTE byParm2 )
{
if( g_byaIrqBuf0[byParm1] & byParm2 )
return( SCRIPT_OK );
else
return( SCRIPT_CHK_FAIL );
}
BYTE ScOrMask( BYTE byParm1, BYTE byParm2 )
{
g_byaIrqBuf0[byParm1] |= byParm2;
return( SCRIPT_OK );
}
BYTE ScAndMask( BYTE byParm1, BYTE byParm2 )
{
g_byaIrqBuf0[byParm1] &= byParm2;
return( SCRIPT_OK );
}
BYTE ScStoreBuf( BYTE byParm1, BYTE byParm2 )
{
BYTE byTmp;
if( byParm2 == 1 ) // Only buffer 1 is supported !
{
byTmp = UsbRead3wV3V4(byParm1); // Read register to clear interrupt
if (g_stIrqBuf1.byF < MAXLEN_IRQRNDBUF)
{
g_stIrqBuf1.byBuf[g_stIrqBuf1.byW] = byTmp;
g_stIrqBuf1.byW++;
if (g_stIrqBuf1.byW == MAXLEN_IRQRNDBUF)
g_stIrqBuf1.byW = 0;
g_stIrqBuf1.byF++;
}
return( SCRIPT_OK );
}
else
return( SCRIPT_ERROR );
}
BYTE ScRead3WD(BYTE byParm1, BYTE byParm2)
{
g_ReplyBuf[2 + byParm2] = UsbRead3wV3V4(byParm1);
return(SCRIPT_OK);
}
BYTE ScPollHi(BYTE byParm1, BYTE byParm2)
{
while ( (UsbRead3wV3V4(byParm1) & byParm2) != byParm2 );
return(SCRIPT_OK);
}
BYTE ScPollLo(BYTE byParm1, BYTE byParm2)
{
while ( (UsbRead3wV3V4(byParm1) & byParm2) != 0 );
return(SCRIPT_OK);
}
// ==============================================================================
#endif //USE_IRQSCRIPT // The whole file can be discarded if interrupt is not used
// ==============================================================================
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -