fir24a0.c
来自「S3C24A0的完整BSP包,对开发此芯片的开发者很有用.」· C语言 代码 · 共 1,319 行 · 第 1/3 页
C
1,319 行
DEBUGFIR(DBGIRDA, (TEXT(" rIRDA_IER - 0x%x\r\n"), (UCHAR)g_pIRDAregs->IRDA_IER));
DEBUGFIR(DBGIRDA, (TEXT(" rIRDA_CNT - 0x%x\r\n"), (UCHAR)g_pIRDAregs->IRDA_CNT));
DEBUGFIR(DBGIRDA, (TEXT(" rIRDA_FCR - 0x%x\r\n"), (UCHAR)g_pIRDAregs->IRDA_FCR));
DEBUGFIR(DBGIRDA, (TEXT(" rIRDA_PLR - 0x%x\r\n"), (UCHAR)g_pIRDAregs->IRDA_PLR));
}
BOOLEAN NdisToFirPacket(IrDevice *thisDev, PNDIS_PACKET Packet, UCHAR *irPacketBuf, UINT irPacketBufLen, UINT *irPacketLen)
{
PNDIS_BUFFER ndisBuf;
UINT ndisPacketBytes = 0;
UINT ndisPacketLen;
LOG(TEXT("==> NdisToFirPacket"), 0);
DEBUGFIR(DBG_OUT, (TEXT("NdisToFirPacket(0x%x)"), (UINT) thisDev));
/*
* Get the packet's entire length and its first NDIS buffer
*/
NdisQueryPacket(Packet, NULL, NULL, &ndisBuf, &ndisPacketLen);
LOG(TEXT("NdisToFirPacket, number of bytes:"), ndisPacketLen);
/*
* Make sure that the packet is big enough to be legal.
* It consists of an A, C, and variable-length I field.
*/
if (ndisPacketLen < IR_ADDR_SIZE + IR_CONTROL_SIZE){
LOG(TEXT("Error: packet too short in "), ndisPacketLen);
DEBUGFIR(DBG_ERR,
(TEXT("FIR, packet too short in NdisToFirPacket (%d bytes)"),
ndisPacketLen));
return FALSE;
}
/*
* Make sure that we won't overwrite our contiguous buffer.
*/
if (ndisPacketLen > irPacketBufLen){
/*
* The packet is too large
* Tell the caller to retry with a packet size large
* enough to get past this stage next time.
*/
DBGOUT((TEXT("Error: packet too large in "), ndisPacketLen));
DEBUGFIR(DBG_ERR,
(TEXT("Packet too large in NdisToIrPacket (%d=%xh bytes), ")
TEXT("MAX_IRDA_DATA_SIZE=%d, irPacketBufLen=%d."),
ndisPacketLen, ndisPacketLen, MAX_IRDA_DATA_SIZE, irPacketBufLen));
*irPacketLen = ndisPacketLen;
return FALSE;
}
/*
* Read the NDIS packet into a contiguous buffer.
* We have to do this in two steps so that we can compute the
* FCS BEFORE applying escape-byte transparency.
*/
while (ndisBuf) {
UCHAR *bufData;
UINT bufLen;
// DBGOUT((TEXT("while (ndisBuf) ")));
NdisQueryBuffer(ndisBuf, (PVOID *)&bufData, &bufLen);
// DBGOUT((TEXT("NdisQueryBuffer ")));
if (ndisPacketBytes + bufLen > ndisPacketLen){
/*
* Packet was corrupt -- it misreported its size.
*/
*irPacketLen = 0;
return FALSE;
}
NdisMoveMemory((PVOID)(irPacketBuf+ndisPacketBytes),
(PVOID)bufData, (ULONG)bufLen);
// DBGOUT((TEXT("NdisMoveMemory")));
ndisPacketBytes += bufLen;
NdisGetNextBuffer(ndisBuf, &ndisBuf);
// DBGOUT((TEXT("NdisGetNextBuffer")));
}
DBGOUT((TEXT("Ir Command byte "), (UINT)*(irPacketBuf+1)));
/*
* Do a validity check on the length of the packet.
*/
if (ndisPacketBytes != ndisPacketLen){
/*
* Packet was corrupt -- it misreported its size.
*/
LOG(TEXT("Error: Packet corrupt in NdisToIrPacket ")
TEXT("(buffer lengths don't add up to packet length)"), 0);
DEBUGFIR(DBG_ERR, (TEXT("Packet corrupt in NdisToIrPacket ")
TEXT("(buffer lengths don't add up to packet length).")));
*irPacketLen = 0;
return FALSE;
}
#ifdef DBG_ADD_PKT_ID
if (addPktIdOn){
static USHORT uniqueId = 0;
DEBUGFIR(DBG_OUT, ("*** --> SEND PKT ID: %xh", (UINT)uniqueId));
LOG("ID: Send (FIR) Pkt id:", uniqueId);
*(USHORT *)(irPacketBuf+ndisPacketBytes) = uniqueId++;
ndisPacketBytes += sizeof(USHORT);
}
#endif
*irPacketLen = ndisPacketBytes;
LOG(TEXT("<== NdisToFirPacket"), 0);
DEBUGFIR(DBG_OUT, (TEXT("<== NdisToFirPacket")));
return TRUE;
}
/* This function initializes the IRDA module and prepares it for
reception or transmission
*/
int Irda_Init_Fir(IrDevice *thisDev)
{
UINT bitsPerSec = thisDev->linkSpeedInfo->bitsPerSec;
// Irda_Stop_Fir();
pIrdaGloabls->bFIREnabled = TRUE;
pIrdaGloabls->bUseDMA = TRUE;
DEBUGFIR(DBGIRDA, (TEXT("==> Irda_Init_Fir \r\n")));
if( bitsPerSec == FIR_SPEED_4000000 ) {
thisDev->firConf.IrMode = S24A0_IRDA_MODEFIR;
}else {
thisDev->firConf.IrMode = S24A0_IRDA_MODEMIR;
if( bitsPerSec == MIR_SPEED_1152000 )
thisDev->firConf.MirMode = S24A0_IRDA_MIRFULLSPEED;
else
thisDev->firConf.MirMode = S24A0_IRDA_MIRFULLSPEED;
}
g_pClkPwrRegs->CLKCON |= IRDA_CLK_ON;
// Timing Control Register
// g_pIRDAregs->IRDA_TIME = 0x7D;;
g_pIRDAregs->IRDA_MDR = (1<<4) | (1<<3)| thisDev->firConf.IrMode; // Sip every frame/HP/Mode
// IrDA Control Register
g_pIRDAregs->IRDA_CNT = (0<<7)|(0<<6)|(0<<5)|(0<<4)|(1<<3)|(0<<1)|(0);
if( thisDev->firConf.IrMode == S24A0_IRDA_MODEMIR ) {
g_pIRDAregs->IRDA_CNT |= thisDev->firConf.MirMode;
}
// Tx disable/Rx disable/Loop disable/MIR full/SIP/No Frame abort/SDBE High
// g_pIRDAregs->IRDA_CNT = (0<<5)|(0<<4)|(0<<3)|(0);
// Mode & Transceiver Set Register
// Set Start Field Register or Preamble length
g_pIRDAregs->IRDA_PLR = (2<<4);
if( thisDev->firConf.IrMode == S24A0_IRDA_MODEFIR ) {
g_pIRDAregs->IRDA_PLR |= (1<<6);
}else {
g_pIRDAregs->IRDA_PLR |= 4;
}
// Interrupt & DMA Control Register
g_pIRDAregs->IRDA_CNF = 0x0; // Disable Interrupt & DMA
// Interrupt Enable Register
g_pIRDAregs->IRDA_IER = 0x0; // Disable All interrupts
// FIFO Control Register
// g_pIRDAregs->IRDA_FCR = (0<<6)|(1<<5)|(1<<2)|(1<<1)|(1);
g_pIRDAregs->IRDA_FCR = 0;
// RX trigger level/FIFO Size/Tx FIFO reset/RX FIFO reset/FIFO enable
// Receive Frame Length Register
g_pIRDAregs->IRDA_RXFLL =0;
g_pIRDAregs->IRDA_RXFLH = 0;
// Transmit Frame Length Register
g_pIRDAregs->IRDA_TXFLL = 0;
g_pIRDAregs->IRDA_TXFLH = 0;
Irda_GPIO_Conf(FALSE);
FirSetupIntRecv(thisDev);
return -1;
}
void Irda_Stop_Fir(void)
{
DEBUGFIR(DBGIRDA, (TEXT("==> Irda_Stop_Fir \r\n")));
#if 1
g_pIRDAregs->IRDA_TIME = 0;
g_pIRDAregs->IRDA_MDR = 0;
g_pIRDAregs->IRDA_CNT = 0;
g_pIRDAregs->IRDA_PLR = 0;
g_pIRDAregs->IRDA_CNF = 0;
g_pIRDAregs->IRDA_IER = 0;
g_pIRDAregs->IRDA_FCR = 3 << 1;
g_pIRDAregs->IRDA_RXFLL =0;
g_pIRDAregs->IRDA_RXFLH = 0;
g_pIRDAregs->IRDA_TXFLL = 0;
g_pIRDAregs->IRDA_TXFLH = 0;
g_pClkPwrRegs->CLKCON &= ~IRDA_CLK_ON;
#endif
pIrdaGloabls->bFIREnabled = FALSE;
pIrdaGloabls->bUseDMA = FALSE;
// g_pIOPregs->GPCON_U &= ~(3<<24)|(3<<22)|(3<<20);
// g_pINTregs->INTMSK &= ~BIT_IRDA_MSTICK;
g_pINTregs->INTSUBMSK |= BIT_SUB_IRDA;
}
void Init_Irda_Rx(int RxLen,int Mode)
{
DEBUGFIR(DBGIRDA, (TEXT("==> Init_Irda_Rx \r\n")));
// Mode & Transceiver Set Register
// g_pIRDAregs->IRDA_MDR = (1<<4) | (1<<3) | 0x4; // Sip every frame/HP/Mode
// g_pIRDAregs->IRDA_TIME = 0x7D; // Check please..... Can't read, only write.
// g_pIRDAregs->IRDA_MDR = (1<<4) | (1<<3) | 0x4; // Sip every frame/HP/Mode
// Interrupt & DMA Control Register
g_pIRDAregs->IRDA_CNT &= ~(3<<6); //Resest Tx and Rx bits
g_pIRDAregs->IRDA_CNF = 0x0; // Disable Interrupt & DMA
// Interrupt Enable Register
g_pIRDAregs->IRDA_IER = 0x0; // Disable All interrupts
// FIFO Control Register
// RX trigger level/FIFO Size/Tx FIFO reset/RX FIFO reset/FIFO enable
// g_pIRDAregs->IRDA_PLR = ((0<<6) | (1<<4) | 4);
// g_pIRDAregs->IRDA_PLR = 0;
// Receive Frame Length Register
g_pIRDAregs->IRDA_RXFLL = RxLen & 0xff;
g_pIRDAregs->IRDA_RXFLH = (RxLen >> 10) & 0x3f;
// Transmit Frame Length Register
g_pIRDAregs->IRDA_TXFLL = 0;
g_pIRDAregs->IRDA_TXFLH = 0;
g_pIRDAregs->IRDA_FCR = (S24A0_IRDA_RXFIFO64_TRIG16<<6)|
(S24A0_IRDA_FIFOSIZE64<<5)|(1<<2)|(1<<1)|(1);
// while(!(g_pIRDAregs->IRDA_FCR & 0x08));
DEBUGFIR(DBGIRDA, (TEXT("==> after while 1 \r\n")));
// Mode & Transceiver Set Register
// g_pIRDAregs->IRDA_IER = 0xFF; // Enisable All interrupts
g_pIRDAregs->IRDA_IER = 1<<6|1<<4|1<<3|1;
g_pIRDAregs->IRDA_CNT |= (1 <<6); //Enable Rx
if(Mode == S24A0_IRDA_RXMODEINT) {
g_pIRDAregs->IRDA_CNF = ((0<<3) | (0<<2)|1); // DMA En | Rx DMA En| Int En
}else{
g_pIRDAregs->IRDA_CNF = ((1<<3) | (1<<2)|0); // DMA En | Rx DMA En| Int En
}
g_pINTregs->INTMSK &= ~BIT_IRDA_MSTICK;
g_pINTregs->INTSUBMSK &= ~BIT_SUB_IRDA;
// DisplayRegs();
return;
}
void Init_Irda_Tx(int TxLen)
{
DEBUGFIR(DBGIRDA, (TEXT("==> Init_Irda_Tx \r\n")));
// Mode & Transceiver Set Register
// g_pIRDAregs->IRDA_MDR = (1<<4) | (1<<3) | 0x4; // Sip every frame/HP/Mode
g_pIRDAregs->IRDA_CNT &= ~(3<<6); //Resest Tx and Rx bits
// Interrupt & DMA Control Register
g_pIRDAregs->IRDA_CNF = 0x0; // Disable Interrupt & DMA
// Interrupt Enable Register
g_pIRDAregs->IRDA_IER = 0x0; // Disable All interrupts
// Receive Frame Length Register
g_pIRDAregs->IRDA_RXFLL = 0;
g_pIRDAregs->IRDA_RXFLH = 0;
// Transmit Frame Length Register
g_pIRDAregs->IRDA_TXFLL = TxLen & 0xff ;
g_pIRDAregs->IRDA_TXFLH = (TxLen >> 8) & 0xff;
// FIFO Control Register
g_pIRDAregs->IRDA_FCR = 0;
g_pIRDAregs->IRDA_FCR = (0<<6)|(1<<5)|(1<<2)|(1<<1)|(1);
// RX trigger level/FIFO Size/Tx FIFO reset/RX FIFO reset/FIFO enable
// g_pIRDAregs->IRDA_PRL = ((0<<6) | (1<<4) | 4);
// while(!(g_pIRDAregs->IRDA_FCR & 0x10));
DEBUGFIR(DBGIRDA, (TEXT("==> after while 1 \r\n")));
// Mode & Transceiver Set Register
g_pIRDAregs->IRDA_CNT &= ~(3<<6); //Disable Rx and Tx
g_pIRDAregs->IRDA_CNT |= 1 <<7; //Enable Tx
g_pIRDAregs->IRDA_CNF = (1<<3) | (0<<2); // Enable Tx DMA
return;
}
BOOLEAN Irda_Int_Tx(IrDevice *thisDev)
{
// NDIS_STATUS stat;
PNDIS_PACKET Packet;
PNDIS_IRDA_PACKET_INFO packetInfo;
int ret_val;
DEBUGMSG(DBGIRDA, (TEXT("==> Irda_Int_Tx(0x%x)\r\n"), (UINT) thisDev));
thisDev->HangChk = 0;
if (IsListEmpty(&thisDev->SendQueue)) {
ret_val = FALSE;
} else {
// thisDev->portInfo.writePending = TRUE;
Packet = HEAD_SEND_PACKET(thisDev);
// Check for min turnaround time set.
packetInfo = GetPacketInfo(Packet);
//
// NOTE: Don't use NdisStallExecution for turnaround delay since
// you shouldn't stall for more than 60 us. Calling
// NdisStallExecution for large times will degrade system
// performance.
//
if (packetInfo->MinTurnAroundTime) {
UINT usecToWait = packetInfo->MinTurnAroundTime;
UINT msecToWait;
packetInfo->MinTurnAroundTime = 0;
// Ndis timer has a 1ms granularity (in theory). Let's round off.
msecToWait = (usecToWait<=1000) ? 1 : (usecToWait+500)/1000;
NdisMSetTimer(&thisDev->TurnaroundTimer, msecToWait);
DEBUGMSG(DBGIRDA, (TEXT("Irda_Int_Tx:- Do min TAT wait\r\n")));
return TRUE; // Say we're successful. We'll come back here.
}
NdisToFirPacket(thisDev,
Packet, (UCHAR *) thisDev->portInfo.writeBuf,
MAX_IRDA_DATA_SIZE, &thisDev->portInfo.writeBufLen);
DEBUGMSG(DBGIRDA, (TEXT("Irda_Int_Tx: Sending packet 0x%x, len = %d\r\n"), Packet, thisDev->portInfo.writeBufLen));
// Initialize the IRDA module with the bytes to be received and transmitted
// Init_Irda(MAX_IRDA_DATA_SIZE, thisDev->writeBufLen);
g_pIRDAregs->IRDA_CNF |= (1); // Enable Tx DMA
g_pIRDAregs->IRDA_CNT |= (1<<7); // Enable Tx
g_pIRDAregs->IRDA_IER = (1<<5)|(1<<1); // Enable Tx underrun/Tx FIFO trigger
DEBUGMSG(DBGIRDA, (TEXT("Irda_Int_Tx: Number of data bytes sent: %x\r\n"), thisDev->portInfo.writeBufLen));
}
DEBUGMSG(DBGIRDA, (TEXT("<== Irda_Int_Tx\r\n")));
return ret_val;
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?