📄 uart.c
字号:
#include <string.h>
#include "board.h"
#include "sdev.h"
#include "uart.h"
#include "bspspec.h" /* add by maold */
/* 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+2].scc.pothers.smc_modem.psmc.u)
#define regs(ch) (pda->smc_regs1[ch])
static void UartStopOp(UartCfgStruct *pCfg)
{
PDA *pda = (PDA *)(GetIMMR() & IO_MAP_MASK);
CPM_CMD(STOP_TX|((pCfg->ch*4+9)<<4));
regs(pCfg->ch).smc_smcmr &= ~3;/*disable tx_rx*/
}
static void UartStartOp(UartCfgStruct *pCfg)
{
PDA *pda = (PDA *)(GetIMMR() & IO_MAP_MASK);
CPM_CMD(INIT_RX_TX_PARAMS|((pCfg->ch*4+9)<<4));
regs(pCfg->ch).smc_smcmr |= 3;/*enable tx_rx*/
}
static void UartClearBuf(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 UartIsr(void* pDataBuf)
{
/* del USHORT starBD,tempstate; by maold */
PDA *pda=(PDA *)(GetIMMR() & IO_MAP_MASK);
DataBufStruct *pData=(DataBufStruct *)pDataBuf;
UartCfgStruct *pCfg =(UartCfgStruct *)(pData+1);
USHORT Events = regs(pCfg->ch).smc_smce;
regs(pCfg->ch).smc_smce = Events;
if((Events & UART_RX_BRK) || (Events & UART_LACK_OF_BUF )
|| (Events & UART_RX_BUF))
{
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 & UART_TX_BUF)
{
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 UartInit(void *pDataBuf, UartCfgStruct *cfg )
{
int i,clkdiv,BrgClk=BspCpuClkRate()*1000000;
USHORT temp_ushort;
BuffDescType *temp_bufdes;
char *pRecvBuf,*pSendBuf;
PDA *pda = (PDA *)(GetIMMR() & IO_MAP_MASK);
DataBufStruct* pData=(DataBufStruct *)pDataBuf;
UartCfgStruct* pCfg =(UartCfgStruct *)(pData+1);
/*-------------------------<< Initial data >>-------------------------------*/
memmove(pCfg,cfg,sizeof(*cfg));
memset(pData, 0, sizeof(DataBufStruct));
pCfg->ch=((cfg->ch)&0x1);
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 >>----------------------*/
UartStopOp(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;
SPLX(S_SI_ModeReg&=(~(0xf000L<<(pCfg->ch*16))))
SPLX(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 */
/* 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;
/* BIT + 1STOP + NOPAR + MODE + NORM */
regs(pCfg->ch).smc_smcmr=(9<<11)+(0<<10)+(0<<9)+(0<<8)+(2<<4)+(0<<2);
regs(pCfg->ch).smc_smce=0xff;
regs(pCfg->ch).smc_smcm=UART_RX_BRK|UART_LACK_OF_BUF
|UART_TX_BUF|UART_RX_BUF;
pda->dma_sdcr=1;
SPLX(pda->cpmi_cimr|=(EN_SMC1 >> pCfg->ch);)
SPLX(pda->cpmi_cipr|=(CLR_SMC1 >> pCfg->ch);)
SPLX(pda->cpmi_cicr|=CPM_EN_INTS|0x1b0000;)
SPLX(CpmIsrAddHandler(V_SMC1-pCfg->ch,UartIsr,(void *)pData); )
UartStartOp(pCfg);
}
static int UartRead(void *pDataBuf,void *pBuf, int MaxLen)
{
return BDRead(pDataBuf,pBuf,MaxLen);
}
static int UartWrite(void *pDataBuf,void *pBuf, int MaxLen)
{
return BDWrite(pDataBuf,pBuf,MaxLen);
}
static int UartCntrl(void *pDataBuf, int cmd, void *pParam, int maxlen)
{
int clkdiv,BrgClk=BspCpuClkRate()*1000000; /* del i by maold*/
/* del ULONG temp_ulong; by maold */
/* del UartCfgStruct cfg; by maold */
PDA *pda= (PDA *)(GetIMMR() & IO_MAP_MASK);
DataBufStruct *pData=(DataBufStruct *)pDataBuf;
UartCfgStruct *pCfg =(UartCfgStruct *)(pData+1);
int ret=BDCntrl(pDataBuf, cmd, pParam, maxlen);
if(ret!=SDE_UNKNOW_CMD)return ret;
switch(cmd)
{
case SDC_REINIT:
UartStopOp(pCfg);
dpram_dealloc(0,(char*)pData->pBaseRecvBD,BD_LEN*pData->MaxRecvBD);
dpram_dealloc(0,(char*)pData->pBaseSendBD,BD_LEN*pData->MaxSendBD);
UartInit(pDataBuf,pCfg);
UartStartOp(pCfg);
break;
case SDC_SET_LOOPBACK_MODE:
UartStopOp(pCfg);
regs(pCfg->ch).smc_smcmr&=~0xc;
regs(pCfg->ch).smc_smcmr|=0x4L;
UartClearBuf(pData);
UartStartOp(pCfg);
break;
case SDC_SET_NORMAL_MODE:
UartStopOp(pCfg);
regs(pCfg->ch).smc_smcmr&=~0xc;
UartClearBuf(pData);
UartStartOp(pCfg);
break;
case SDC_SEND_BREAK:
CPM_CMD(STOP_TX|((pCfg->ch*4+9)<<4))
CPM_CMD(RESTART_TX|((pCfg->ch*4+9)<<4));
break;
case SDC_SET_BAUDRATE:
pCfg->BaudRate=*(int *)pParam;
if(pCfg->BaudRate > BrgClk/16 )
pCfg->BaudRate=BrgClk/16;
else if(pCfg->BaudRate < BrgClk/(16*16*4096))
pCfg->BaudRate=BrgClk/(256*4096);
UartStopOp(pCfg);
clkdiv = (BrgClk)/(16*pCfg->BaudRate) - 1;
if(clkdiv >= 4096)
clkdiv=((BrgClk/(16*16*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 */
UartClearBuf(pData);
UartStartOp(pCfg);
break;
default:
return SDE_UNKNOW_CMD;
}/* end of switch(cmd) */
return 0;
}
UCHAR *UartBspInit(int DEV, UCHAR *FreeMemPtr, UartCfgStruct *cfg)
{
cfg->UncachedBuffer
=AllocUncachedBuffer((cfg->MaxRecvBD+cfg->MaxSendBD)*cfg->MaxBufLen,4);
InstallSD(DEV,UartRead,UartWrite,UartCntrl,FreeMemPtr);
UartInit(FreeMemPtr, cfg);
FreeMemPtr += sizeof(DataBufStruct)+sizeof(UartCfgStruct);
memcpy(FreeMemPtr,"*UartDat",8);
FreeMemPtr += 8;
return FreeMemPtr;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -