UART的使用需要经历 open、read/write、close三个阶段,即在使用某个UART Port用于数据传输等操作时,需要先调用UART DRIVER提供的open
函数先打开对应的uart port,然后在需要read/write的地方进行读写操作,当UART使用完毕后最好调用close函数关闭对应的uart port以便其他模块来使用。
通常情况下一个uart port只会给一个模块来使用,不存在动态切换port的情况,所以就可以省略close的动作。具体的demo code如下:
1、 对于11A及之后的代码,uart相关的操作都放在uart_handler中,通过形如SIO_CMD_OPEN、SIO_CMD_CLOSE等cmd来实现基本操作。所以当在自己模块中需
要对UART操作时,可以按照下面的方式对这些基本操作的cmd进行简单的封装,如下:
static DCL_UINT16 UART_CheckTxAllSentOut(DCL_DEV port)
{
DCL_HANDLE handle;
UART_CTRL_CHECK_TSO_T data;
handle = DclSerialPort_Open(port,0);
DclSerialPort_Control(handle,UART_CMD_CHECK_TX_SEND_OUT, (DCL_CTRL_DATA_T*)&data);
DclSerialPort_Close(handle);
return data.bFlag;
}
static void UART_ClrRxBuffer(UART_PORT port, module_type ownerid)
{
DCL_HANDLE handle;
UART_CTRL_CLR_BUFFER_T data;
data.u4OwenrId = ownerid;
handle = DclSerialPort_Open(port,0);
DclSerialPort_Control(handle,SIO_CMD_CLR_RX_BUF, (DCL_CTRL_DATA_T*)&data);
}
static void UART_ClrTxBuffer(UART_PORT port, module_type ownerid)
{
DCL_HANDLE handle;
UART_CTRL_CLR_BUFFER_T data;
data.u4OwenrId = ownerid;
handle = DclSerialPort_Open(port,0);
DclSerialPort_Control(handle,SIO_CMD_CLR_TX_BUF, (DCL_CTRL_DATA_T*)&data);
}
static DCL_UINT16 UART_GetBytesAvail(DCL_DEV port)
{
DCL_HANDLE handle;
UART_CTRL_RX_AVAIL_T data;
handle = DclSerialPort_Open(port,0);
DclSerialPort_Control(handle,SIO_CMD_GET_RX_AVAIL, (DCL_CTRL_DATA_T*)&data);
DclSerialPort_Close(handle);
return data.u2RetSize;
}
static kal_uint16 UART_PutBytes(UART_PORT port, kal_uint8 *Buffaddr, kal_uint16 Length, module_type ownerid)
{
DCL_HANDLE handle;
UART_CTRL_PUT_BYTES_T data;
//UART_CTRL_PUT_UART_BYTE_T data;
data.u4OwenrId = ownerid;
data.u2Length = Length;
data.puBuffaddr = Buffaddr;
handle = DclSerialPort_Open(port,0);
DclSerialPort_Control(handle,SIO_CMD_PUT_BYTES, (DCL_CTRL_DATA_T*)&data);
return data.u2RetSize;
}
static kal_uint16 UART_GetBytes(UART_PORT port, kal_uint8 *Buffaddr, kal_uint16 Length, kal_uint8 *status, module_type ownerid)
{
DCL_HANDLE handle;
UART_CTRL_GET_BYTES_T data;
data.u4OwenrId = ownerid;
data.u2Length = Length;
data.puBuffaddr = Buffaddr;
data.pustatus = status;
handle = DclSerialPort_Open(port,0);
DclSerialPort_Control(handle,SIO_CMD_GET_BYTES, (DCL_CTRL_DATA_T*)&data);
return data.u2RetSize;
}
static void UART_TurnOnPower(UART_PORT port, kal_bool on)
{
DCL_HANDLE handle;
UART_CTRL_POWERON_T data;
handle = DclSerialPort_Open(port, 0);
data.bFlag_Poweron = on;
DclSerialPort_Control(handle, UART_CMD_POWER_ON, (DCL_CTRL_DATA_T*)&data);
DclSerialPort_Close(handle);
}
static void UART_SetDCBConfig(DCL_DEV port, UART_CONFIG_T *UART_Config, DCL_UINT32 ownerid)
{
DCL_HANDLE handle;
UART_CTRL_DCB_T data;
data.u4OwenrId = ownerid;
data.rUARTConfig.u4Baud = UART_Config->u4Baud;
data.rUARTConfig.u1DataBits = UART_Config->u1DataBits;
data.rUARTConfig.u1StopBits = UART_Config->u1StopBits;
data.rUARTConfig.u1Parity = UART_Config->u1Parity;
data.rUARTConfig.u1FlowControl = UART_Config->u1FlowControl;
data.rUARTConfig.ucXonChar = UART_Config->ucXonChar;
data.rUARTConfig.ucXoffChar = UART_Config->ucXoffChar;
data.rUARTConfig.fgDSRCheck = UART_Config->fgDSRCheck;
handle = DclSerialPort_Open(port,0);
DclSerialPort_Control(handle,SIO_CMD_SET_DCB_CONFIG, (DCL_CTRL_DATA_T*)&data);
DclSerialPort_Close(handle);
}
static kal_bool UART_Open(UART_PORT port, module_type ownerid)
{
DCL_HANDLE handle;
UART_CTRL_OPEN_T data;
DCL_STATUS status;
data.u4OwenrId = ownerid;
handle = DclSerialPort_Open(port,0);
status = DclSerialPort_Control(handle,SIO_CMD_OPEN, (DCL_CTRL_DATA_T*)&data);
if(STATUS_OK != status)
return KAL_FALSE;
else
return KAL_TRUE;
}
static module_type UART_GetOwnerID(UART_PORT port)
{
DCL_HANDLE handle;
UART_CTRL_OWNER_T data;
handle = DclSerialPort_Open(port,0);
DclSerialPort_Control(handle,SIO_CMD_GET_OWNER_ID, (DCL_CTRL_DATA_T*)&data);
return (module_type)(data.u4OwenrId);
}
static void UART_SetOwner(UART_PORT port, module_type ownerid)
{
DCL_HANDLE handle;
UART_CTRL_OWNER_T data;
data.u4OwenrId = ownerid;
handle = DclSerialPort_Open(port,0);
DclSerialPort_Control(handle,SIO_CMD_SET_OWNER, (DCL_CTRL_DATA_T*)&data);
}
2、 UART初始化示例代码:
kal_uint8 uart3_handler = 0xff;
#define IR_COMM_PORT uart_port3
#define IR_COMM_OWNER_ID MOD_MMI
void myUART_Iint(void)
{
kal_bool status3;
uart3_handler = L1SM_GetHandle();
L1SM_SleepDisable(uart3_handler); //注意调用此函数后会lock sleep,造成系统无法sleep,所以如果希望系统可以sleep时,在数据发送完成后没有数据
//发送 时需调用L1SM_SleepEnable()函数来释放该handler。
//对UART TX RX对应的GPIO进行配置,注意配置包括mode dir ,示例部分只配置了mode。这部分也可以在dct tool中设定
GPIO_ModeSetup(20,1); //open uart3
GPIO_ModeSetup(21,1);
//开启uart power
UART_TurnOnPower(IR_COMM_PORT, KAL_TRUE); //open uart
//防止需要使用的uart port被其他模块所打开,故使用如下函数可以来check
IR_Owner_save = UART_GetOwnerID(IR_COMM_PORT);
status3 = UART_Open(IR_COMM_PORT, IR_COMM_OWNER_ID);
assert(status3 == KAL_TRUE); //如果UART OPEN成功返回KAL_TRUE,故此处检查uart是否open成功。
// 设定uart 波特率等信息,注意在调用此函数之前需要先初始化Dcb结构体
UART_SetDCBConfig(IR_COMM_PORT, &Dcb, IR_COMM_OWNER_ID);
}
至此整个UART常用API的封装及初始化部分已经完成,接下来的工作就是在对于的task调用对应的API来接收和发送数据。
3、 在task使用uart进行数据read/write的方法如下:假设目前需要在Test_task中进行数据read/write,该task mian函数为Test_TaskMain()
static vodi Test_TaskMain(task_entry_struct * task_entry_ptr)
{
//==========================================
//此处可以加入用户需要的初始化内容
//===========================================
myUART_Iint(); //调用上面第2 步构造的uart 初始化函数
//===========================================
// 其他的初始化部分
//============================================
while(1)
{
receive_msg_ext_q(task_info_g[task_entry_ptr->task_indx].task_ext_qid, ¤t_ilm);
switch(current_ilm.msg_id)
{
case MSG_ID_UART_READY_TO_READ_IND:
avail = UART_GetBytesAvail(IR_COMM_PORT);
if( avail )
{
readSize = UART_GetBytes(IR_COMM_PORT, (kal_uint8*)buf, bsize, NULL, IR_COMM_OWNER_ID);
readTotal += avail;
}
break;
case MSG_ID_UART_READY_TO_WRITE_IND:
sentSize = UART_PutBytes(IR_COMM_PORT, (kal_uint8 *)buf, bsize, IR_COMM_OWNER_ID);
if(sentSize < bsize)
{
//如果此条件满足,表明实际发送的数据比期望发送的数据少,即期望发送bsize个数据,而实际发送了sentsize个数据。
//所以需要在下一个MSG_ID_UART_READY_TO_WRITE_IND来临后调用UART_PutBytes发送剩余的(bsize-sentsize)的数据
}
break;
.
.
//其他msg的处理这里省略
default:
break;
}
}