?? sccuart.c
字號:
#include "board.h"
#include "sdev.h"
#include "uart.h"
#include "sccuart.h"
#define SCCM_GLR (1L<<(15-3))
#define SCCM_GLT (1L<<(15-4))
#define SCCM_AB (1L<<(15-6))
#define SCCM_IDL (1L<<(15-7))
#define SCCM_GRA (1L<<(15-8))
#define SCCM_BRKE (1L<<(15-9))
#define SCCM_BRKS (1L<<(15-10))
#define SCCM_CCR (1L<<(15-12))
#define SCCM_BSY (1L<<(15-13))
#define SCCM_TX (1L<<(15-14))
#define SCCM_RX (1L)
/* SMCMR */
#define UART_LOOPBACK (1<<(15-13))
/* SMCE Flags */
#define UART_RX_BRKE (1<<(7-1))
#define UART_RX_BRK (1<<(7-3))
#define UART_LACK_OF_BUF (1<<(7-5))
#define UART_TX_BUF (1<<(7-6))
#define UART_RX_BUF (1<<(7-7))
/* Rx BD Flags */
#define UART_RX_ID (1<<(15-7))
#define UART_RX_BR (1<<(15-10))
#define UART_FRAME_ERR (1<<(15-11))
#define UART_PARITY_ERR (1<<(15-12))
#define UART_OVERRUN (1<<(15-14))
/* Tx BD Flags */
#define UART_PREAMBLE (1<<(15-7))
#ifdef param
#undef param
#endif
#ifdef regs
#undef regs
#endif
#define param(ch) (pda->pram[ch].scc.pscc.u)
#define regs(ch) (pda->Scc_regs[ch])
static void SccUartStopOp(SccUartCfgStruct *pCfg)
{
PDA *pda=(PDA *)(GetIMMR() & IO_MAP_MASK);
CPM_CMD(STOP_TX| ( (pCfg->ch*4)<<4 ));
regs(pCfg->ch).scc_gsmra&=~0x00000030;/*disable tx_rx*/
}
static void SccUartStartOp(SccUartCfgStruct *pCfg)
{
PDA *pda=(PDA *)(GetIMMR() & IO_MAP_MASK);
CPM_CMD(INIT_RX_TX_PARAMS| ( (pCfg->ch*4)<<4 ));
regs(pCfg->ch).scc_gsmra |= 0x00000030;/*enable tx_rx*/
}
static void SccUartClearBuf(DataBufStruct *pData)
{
int i;
pData->CurRecvBD=pData->CurSendBD=0;
for(i=0;i<pData->MaxRecvBD;i++)
pData->pBaseRecvBD[i].status = BD_EMPTY|BD_INTR;
if(i>0)pData->pBaseRecvBD[i-1].status |= BD_WRAP;
for(i=0;i<pData->MaxSendBD;i++)
pData->pBaseSendBD[i].status = BD_INTR|BD_LAST;
if(i>0)pData->pBaseSendBD[i-1].status |= BD_WRAP;
}
static void SccUartIsr(void* pDataBuf)
{
USHORT starBD,tempstate;
USHORT Events;
PDA *pda=(PDA *)(GetIMMR() & IO_MAP_MASK);
DataBufStruct *pData=(DataBufStruct *)pDataBuf;
SccUartCfgStruct *pCfg =(SccUartCfgStruct *)(pData+1);
Events = regs(pCfg->ch).scc_scce;
regs(pCfg->ch).scc_scce = Events;
if((Events & SCCM_BRKS) || (Events & SCCM_BSY )
|| (Events & SCCM_RX))
{
pData->DrvInfo.TotalRecvInt++;
if( (pData->RecvEv!=NULL) && (pData->RecvTid!=NULL) )
ev_send(pData->RecvTid,pData->RecvEv);
if(pData->RecvQID!=NULL)
q_send(pData->RecvQID,pData->RecvMessage);
}
if (Events & SCCM_TX)
{
pData->DrvInfo.TotalSendInt++;
if( (pData->SendEv!=NULL) && (pData->SendTid!=NULL) )
ev_send(pData->SendTid,pData->SendEv);
if(pData->SendQID!=NULL)
q_send(pData->SendQID,pData->SendMessage);
}
}/* End of UartIsr */
static void SccUartInit(void *pDataBuf, SccUartCfgStruct *cfg )
{
ULONG tt;
int i,clkdiv;
USHORT temp_ushort;
BuffDescType *temp_bufdes;
char *pRecvBuf,*pSendBuf;
PDA *pda = (PDA *)(GetIMMR() & IO_MAP_MASK);
DataBufStruct* pData=(DataBufStruct *)pDataBuf;
SccUartCfgStruct* pCfg =(SccUartCfgStruct *)(pData+1);
int BrgClk=BspCpuClkRate()*1000000;
/*-------------------------<< Initial data >>-------------------------------*/
memmove(pCfg,cfg,sizeof(*cfg));
memset(pData, 0, sizeof(DataBufStruct));
pCfg->ch=(cfg->ch&0x3);
pData->MaxRecvBD=pCfg->MaxRecvBD;
pData->MaxSendBD=pCfg->MaxSendBD;
pData->MaxBufLen=pCfg->MaxBufLen;
pData->RecvErrMask=UART_FRAME_ERR|UART_PARITY_ERR|UART_OVERRUN;
pData->SendErrMask=0;
pData->UncachedBuffer=pRecvBuf=pCfg->UncachedBuffer;
pSendBuf=(char*)(pRecvBuf+( pData->MaxRecvBD)*(pData->MaxBufLen));
/*-------------------------<< stop SCCx operation >>----------------------*/
SccUartStopOp(pCfg);
if(pCfg->BaudRate > BrgClk/16 )pCfg->BaudRate=BrgClk/16;
else if(pCfg->BaudRate < BrgClk/(16*16*4096))
pCfg->BaudRate=BrgClk/(256*4096);
clkdiv = (BspCpuClkRate()*1000000)/(16*pCfg->BaudRate) - 1;
if(clkdiv >= 4096)
clkdiv=(((BspCpuClkRate()*1000000)/(16*16*pCfg->BaudRate)-1)<<1) | 1;
else
clkdiv <<= 1;
*(&pda->brgc1+pCfg->BRG)|=(1L<<(31-14)); /*reset*/ /*brgclk=40MHZ */
*(&pda->brgc1+pCfg->BRG)=(1L<<(31-15))+clkdiv;
/* Mode don't need at SCC UART mode */
/*
pda->si_simode&=~(0xf000L<<(pCfg->ch*16));
pda->si_simode|=((ULONG)pCfg->BRG<<12)<<(pCfg->ch*16);
*/
/*----------------------<< init SCCx >>-----------------------------------*/
param(pCfg->ch).mrblr=pData->MaxBufLen;
param(pCfg->ch).rfcr=0x18;
param(pCfg->ch).tfcr=0x18;
param(pCfg->ch).max_idl=pCfg->MaxIdle; /* disable max idl function */
param(pCfg->ch).brkec=0;
param(pCfg->ch).brkcr=2; /* break counter */
param(pCfg->ch).parec=0;
param(pCfg->ch).frmer=0;
param(pCfg->ch).nosec=0;
for(i=0;i<8;param(pCfg->ch).cc[i]=0x8000,i++);
if(pCfg->ccLen>0 && pCfg->ccLen<=8)
for(i=0;i<pCfg->ccLen;i++)param(pCfg->ch).cc[i]=pCfg->cc[i];
param(pCfg->ch).rccm=0xc0ff;
/* rx */
temp_ushort=(unsigned short)dpram_alloc(0,pData->MaxRecvBD*BD_LEN);
param(pCfg->ch).rbase = temp_ushort-0X2000;
temp_bufdes=pData->pBaseRecvBD=(BuffDescType *)((char *)pda + temp_ushort);
for(i=0;i<pData->MaxRecvBD;i++)
{
temp_bufdes[i].status=BD_EMPTY|BD_INTR;
temp_bufdes[i].length=0;
temp_bufdes[i].address=pRecvBuf+i*pData->MaxBufLen;
}
if(i>0)temp_bufdes[i-1].status|=BD_WRAP;
/* tx */
temp_ushort=(unsigned short)dpram_alloc(0,pData->MaxSendBD*BD_LEN);
param(pCfg->ch).tbase = temp_ushort-0X2000;
temp_bufdes=pData->pBaseSendBD=(BuffDescType *)((char *)pda+temp_ushort);
for(i=0;i<pData->MaxSendBD;i++)
{
temp_bufdes[i].status=BD_INTR|BD_LAST;
temp_bufdes[i].length=pData->MaxBufLen;
temp_bufdes[i].address=pSendBuf+i*pData->MaxBufLen;
}
if(i>0)temp_bufdes[i-1].status|=BD_WRAP;
/*
regs(pCfg->ch).scc_gsmra=GSMRL_TPL|GSMRL_TPP|GSMRL_TDCR|GSMRL_RDCR|\
GSMRL_RENC|GSMRL_TENC|GSMRL_DIAG_NORMAL\
|GSMRL_ENR|GSMRL_ENT|GSMRL_MODE;
regs(pCfg->ch).scc_gsmrb=GSMRH_TRXTTX|\
GSMRH_TFL|GSMRH_RFW|\
GSMRH_RTSM;
regs(pCfg->ch).scc_psmr=PSMR_CL|PSMR_UM;
*/
regs(pCfg->ch).scc_gsmra=0x00028004;
regs(pCfg->ch).scc_gsmrb=0x00000020;
regs(pCfg->ch).scc_psmr=0x3000;
regs(pCfg->ch).scc_scce=0XFFFF;
regs(pCfg->ch).scc_todr=0x0;
regs(pCfg->ch).scc_dsr=0x7e7E;
/*
regs(pCfg->ch).scc_sccs=
tt= (cfg->BRG<<3+cfg->BRG)<<((pCfg->ch)*8);
*/
regs(pCfg->ch).scc_sccm=SCCM_BRKS|SCCM_BSY|SCCM_TX|SCCM_RX;
SPLX(pda->si_sicr &=( ~(0x3fL<<((pCfg->ch)*8)) );)
SPLX(pda->si_sicr|=(cfg->BRG*8+cfg->BRG)<<((pCfg->ch)*8);)
SPLX(pda->cpmi_cimr|=(EN_SCC1 >> pCfg->ch);)
SPLX(pda->cpmi_cipr|=(CLR_SCC1 >> pCfg->ch);)
SPLX(pda->cpmi_cicr|=CPM_EN_INTS|0x1b0000;)
pda->dma_sdcr=1;
SPLX(CpmIsrAddHandler(V_SCC1-pCfg->ch,SccUartIsr,(void *)pDataBuf); )
SccUartStartOp(pCfg);
}
static int SccUartRead(void *pDataBuf,void *pBuf, int MaxLen)
{
return BDRead(pDataBuf,pBuf,MaxLen);
}
static int SccUartWrite(void *pDataBuf,void *pBuf, int MaxLen)
{
return BDWrite(pDataBuf,pBuf,MaxLen);
}
static int SccUartCntrl(void *pDataBuf, int cmd, void *pParam, int maxlen)
{
int i,clkdiv;
ULONG temp_ulong;
SccUartCfgStruct cfg;
PDA *pda= (PDA *)(GetIMMR() & IO_MAP_MASK);
DataBufStruct *pData=(DataBufStruct *)pDataBuf;
SccUartCfgStruct *pCfg =(SccUartCfgStruct *)(pData+1);
int ret=BDCntrl(pDataBuf, cmd, pParam, maxlen);
if(ret!=SDE_UNKNOW_CMD)return ret;
switch(cmd)
{
case SDC_REINIT:
SccUartStopOp(pCfg);
dpram_dealloc(0,(char*)pData->pBaseRecvBD,BD_LEN*pData->MaxRecvBD);
dpram_dealloc(0,(char*)pData->pBaseSendBD,BD_LEN*pData->MaxSendBD);
SccUartInit(pDataBuf,pCfg);
SccUartStartOp(pCfg);
break;
case SDC_SET_LOOPBACK_MODE:
SccUartStopOp(pCfg);
temp_ulong = regs(pCfg->ch).scc_gsmra;
temp_ulong &= ~0x000000c0;
temp_ulong |= 0x00000040; /* scc internal loopback mode */
regs(pCfg->ch).scc_gsmra = temp_ulong;
SccUartClearBuf(pData);
SccUartStartOp(pCfg);
break;
case SDC_SET_NORMAL_MODE:
SccUartStopOp(pCfg);
temp_ulong = regs(pCfg->ch).scc_gsmra;
temp_ulong &= ~0x000000c0L;
regs(pCfg->ch).scc_gsmra = temp_ulong;
SccUartClearBuf(pData);
SccUartStartOp(pCfg);
break;
case SDC_SEND_BREAK:
CPM_CMD(STOP_TX|((pCfg->ch*4)<<4));
CPM_CMD(RESTART_TX|((pCfg->ch*4)<<4));
break;
case SDC_SET_BAUDRATE:
pCfg->BaudRate=*(int *)pParam;
SccUartStopOp(pCfg);
clkdiv = (BspCpuClkRate()*1000000)/(16*pCfg->BaudRate) - 1;
if(clkdiv >= 4096)
clkdiv=(((BspCpuClkRate()*1000000)/(256*pCfg->BaudRate)-1)<<1)|1;
else
clkdiv <<= 1;
*(&pda->brgc1+pCfg->BRG)|=(1L<<(31-14));
*(&pda->brgc1+pCfg->BRG)=(1L<<(31-15))+clkdiv; /* brgclk=40MHZ */
SccUartClearBuf(pData);
SccUartStartOp(pCfg);
break;
default:
return SDE_UNKNOW_CMD;
}/* end of switch(cmd) */
return 0;
}
char *SccUartBspInit(int DEV, char *FreeMemPtr, SccUartCfgStruct *cfg)
{
cfg->UncachedBuffer
=AllocUncachedBuffer((cfg->MaxRecvBD+cfg->MaxSendBD)*cfg->MaxBufLen,4);
InstallSD(DEV,SccUartRead,SccUartWrite,SccUartCntrl,FreeMemPtr);
SccUartInit(FreeMemPtr, cfg);
FreeMemPtr += sizeof(DataBufStruct)+sizeof(SccUartCfgStruct);
memcpy(FreeMemPtr,"*SccUart",8);
FreeMemPtr += 8;
return FreeMemPtr;
}
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -