📄 rxbin.c
字号:
/*
================================================================================
* @file RxBin.c
* @brief Process UART binary reception
* @author 2006/03/29 Michiru Kagaya
* Copyright (C)SEIKO EPSON Corp. All Rights Reserved.
================================================================================
*/
//=================================
// Include files
//=================================
#include <string.h>
#include "UART_FUNC.h"
#include "UART_FuncCom.h"
#include "UART_IF.h"
//=================================
// Function prototype
//=================================
short RcvCallback( unsigned short wMsg, unsigned short wStatus, void* pRxChannel );
extern short RcvTxtCallback( unsigned short wMsg, unsigned short wStatus, void* pRxChannel );
/*
--------------------------------------------------------------------------------
* UART_FuncReceiveDataA
* @brief Receive data (Asynchronous)
* @param unsigned char bChannel : Channel number of the transmission
* unsigned short wSize : Number of transmission
* unsigned char *pData : Transmission data pointer
* UART_FUNC_CALLBACK pfnCallbackProc
* : Transmision complete notification function pointer
* @retval short
* STATUS_SUCCESS : Complete normally
* STATUS_INVALID_PARAMETER: Parameter error
--------------------------------------------------------------------------------
*/
short UART_FuncReceiveDataA ( unsigned char bChannel, unsigned short wSize,
unsigned char *pData, UART_FUNC_CALLBACK pfnCallbackProc )
{
PRX_INFO psRxInfo = NULL;
unsigned char index = 0;
//===============================
// Check parameter
//===============================
if( wSize == 0 || pData == NULL || bChannel == 0 || bChannel > MAX_UART_CHANNEL ){
return STATUS_INVALID_PARAMETER;
}
index = (unsigned char)(bChannel - 1);
psRxInfo = &sModuleInfo.sChInfo[index].rxInfo;
// Does not the number of transmission exceed the size of sheltering buffer?
if( wSize > psRxInfo->wTempSize ){
return STATUS_UNSUCCESSFUL;
}
//===============================
// Check the state
//===============================
if( sModuleInfo.sChInfo[index].state < STATE_READY ){
return STATUS_UNSUCCESSFUL;
}
if( psRxInfo->state == TRAN_STATE_BUF_OVERFLOW ){
// Befor the API is called, the buffer is overflow.
psRxInfo->state = TRAN_STATE_READY; // Return the state
return UART_FUNC_STATUS_BUF_OVERFLOW;
}
if( psRxInfo->state != TRAN_STATE_READY ){
return STATUS_UNSUCCESSFUL; // In transmiting
}
//===============================
// Save the data
//===============================
psRxInfo->wActSize = 0;
psRxInfo->wReqSize = wSize;
psRxInfo->pReqAddr = pData;
psRxInfo->pPutAddr = pData; // Set the receive address
psRxInfo->pfnCallback = pfnCallbackProc;
//===============================
// Read data processing
//===============================
// Confirm if the data is collected in the internal buffer
//-----------------------------------------
UART_DISABLE_INT(); // Disable the interrupt
if( psRxInfo->wRcvdSize != 0 ){
// There is received data
if( wSize <= psRxInfo->wRcvdSize ){
// --- When all required data had been received ---
UART_FUNC_XFER_RESULT sXferResult;
// Copy data
sXferResult.bChannel = bChannel;
sXferResult.pBufAddr = pData;
sXferResult.wActSize = sXferResult.wReqSize = wSize;
memcpy( pData, psRxInfo->pTempBuf, wSize ); // Copy data
// Update data number
psRxInfo->wRcvdSize -= wSize;
memcpy( psRxInfo->pTempBuf, psRxInfo->pTempBuf + wSize, psRxInfo->wRcvdSize );
// Callback notification
UART_ENABLE_INT(); // Enable the interrupt
psRxInfo->pfnCallback( UART_FUNCM_RCV_DATA_CMP, STATUS_SUCCESS, &sXferResult );
}else{
// There are data and not meet the number of required number of data.
// Copy the collected data number
psRxInfo->wActSize = psRxInfo->wRcvdSize;
memcpy( psRxInfo->pPutAddr, psRxInfo->pTempBuf, psRxInfo->wRcvdSize );
psRxInfo->pPutAddr += psRxInfo->wRcvdSize;
psRxInfo->wRcvdSize = 0;
}
}
UART_ENABLE_INT(); // Enable the interrupt
// Set to waiting for receive data
//-------------------------
psRxInfo->state = TRAN_STATE_EXEC_BINASYNC; // Set to executing data transmission
return STATUS_SUCCESS;
}
/*
--------------------------------------------------------------------------------
* UART_FuncReceiveData
* @brief Receive data
* @param unsigned char bChannel : Channel number of the transmission
* unsigned short wSize : Number of tranmission
* unsigned char *pData : Transmission data pointer
* @retval short
* STATUS_SUCCESS : Complete normally
* STATUS_INVALID_PARAMETER: Parameter error
--------------------------------------------------------------------------------
*/
short UART_FuncReceiveData ( unsigned char bChannel, unsigned short wSize, unsigned char *pData )
{
PRX_INFO psRxInfo = NULL;
volatile unsigned char *pTranState = NULL;
unsigned char index;
//===============================
// Check parameter
//===============================
if( wSize == 0 || pData == NULL || bChannel == 0 || bChannel > MAX_UART_CHANNEL ){
return STATUS_INVALID_PARAMETER;
}
index = (unsigned char)(bChannel-1);
// Does not the number of transmission exceed the size of sheltering buffer?
psRxInfo = &sModuleInfo.sChInfo[index].rxInfo;
if( wSize > psRxInfo->wTempSize ){
return STATUS_UNSUCCESSFUL;
}
//===============================
// Check the state
//===============================
if( sModuleInfo.sChInfo[index].state < STATE_READY ){
return STATUS_UNSUCCESSFUL;
}
if( psRxInfo->state == TRAN_STATE_BUF_OVERFLOW ){
// Befor the API is called, the buffer is overflow.
psRxInfo->state = TRAN_STATE_READY; // Return the state
return UART_FUNC_STATUS_BUF_OVERFLOW;
}
if( psRxInfo->state != TRAN_STATE_READY ){
return STATUS_UNSUCCESSFUL; // In transmiting
}
if( sModuleInfo.sChInfo[index].state < STATE_READY ){
return STATUS_UNSUCCESSFUL;
}
//===============================
// Save the data
//===============================
psRxInfo->wActSize = 0;
psRxInfo->wReqSize = wSize;
psRxInfo->pReqAddr = pData;
psRxInfo->pPutAddr = pData; // Set the receive address
psRxInfo->pfnCallback = NULL;
//===============================
// Receive data processing
//===============================
// Confirm if the data is collected in the internal buffer
//-----------------------------------------
UART_DISABLE_INT(); // Disable the interrupt
if( psRxInfo->wRcvdSize != 0 ){
// There is received data
if( wSize <= psRxInfo->wRcvdSize ){
// --- When all required data had been received ---
memcpy( pData, psRxInfo->pTempBuf, wSize ); // Copy data
// Update data number
psRxInfo->wRcvdSize -= wSize;
memcpy( psRxInfo->pTempBuf, psRxInfo->pTempBuf + wSize, psRxInfo->wRcvdSize );
// Callback notification
UART_ENABLE_INT();
return STATUS_SUCCESS;
}else{
// There are data and not meet the number of required number of data.
// Copy the collected data number
psRxInfo->wActSize = psRxInfo->wRcvdSize;
memcpy( psRxInfo->pPutAddr, psRxInfo->pTempBuf, psRxInfo->wRcvdSize );
psRxInfo->pPutAddr += psRxInfo->wRcvdSize;
psRxInfo->wRcvdSize = 0;
}
}
UART_ENABLE_INT();
//===============================
// Receive data processing
//===============================
psRxInfo->state = TRAN_STATE_EXEC_BINSYNC; // Set to executing data transmission
pTranState = &psRxInfo->state;
do {
UART_DELAY( UART_DELAY_TIME ); // Waiting for the transmission complete
}while( *pTranState != TRAN_STATE_CMP );
psRxInfo->state = TRAN_STATE_READY;
return STATUS_SUCCESS;
}
/*
--------------------------------------------------------------------------------
* RcvCallback
* @brief The function used to receive the Reception callback from the lower module
* @param unsigned short wMsg : UART_IF_RCVD_DATA enters
* unsigned short wStatus : Reception status
* void* pRxChannel : Reception channel number
* @retval short
* STATUS_SUCCESS : Complete normally
--------------------------------------------------------------------------------
*/
short RcvCallback( unsigned short wMsg, unsigned short wStatus, void* pRxChannel )
{
unsigned char ch = 0,
index = 0;
unsigned short wRxStatus = 0;
unsigned short wReadSize = 0;
UART_FUNC_XFER_RESULT sXferResult;
PRX_INFO psRxInfo;
//===============================
// Data reception process
//===============================
if( wMsg != UART_IF_RCVD_DATA || pRxChannel == NULL ){
return STATUS_INVALID_PARAMETER;
}
ch = *(unsigned char *)pRxChannel;
if( ch == 0 || ch > MAX_UART_CHANNEL ){
return STATUS_INVALID_PARAMETER;
}
index = *(unsigned char *)pRxChannel-1;
psRxInfo = &sModuleInfo.sChInfo[index].rxInfo;
// --- The string reception is being processed.
if( psRxInfo->state == TRAN_STATE_EXEC_TXTSYNC
|| psRxInfo->state == TRAN_STATE_EXEC_TXTASYNC ){
// It is string manipulation,then to the routine for the string
return RcvTxtCallback( wMsg, wStatus, pRxChannel );
}
//=========================================
// It confirms whether there is API call,then processes corresponding to the result.
//=========================================
if( psRxInfo->state == TRAN_STATE_READY ){
// Data had been received before the call of API.
//-----------------------------
// --- Check the status ---
if( wStatus != STATUS_SUCCESS ){
// Report the error to the Upper module
psRxInfo->pfnRcvdCallback( UART_FUNCM_RCVD_DATA, (unsigned short)UART_IF_STATUS_HW_ERROR, pRxChannel );
}else{
// STATUS_SUCCESS
// Confirm the number of reception times
if( psRxInfo->wRcvdSize == 0 ){
// Receive for the first time
UART_IFReadData( ch, psRxInfo->wTempSize, psRxInfo->pTempBuf, &wReadSize ); // 1Byte transmission request
psRxInfo->wRcvdSize = wReadSize;
psRxInfo->pfnRcvdCallback( UART_FUNCM_RCVD_DATA, STATUS_SUCCESS, pRxChannel );
}else{
// Reception since the second times
if( psRxInfo->wRcvdSize >= psRxInfo->wTempSize ){
unsigned char temp;
// It changes the state because the internal buffer became full.
psRxInfo->state = TRAN_STATE_BUF_OVERFLOW;
// In the FIFO, delete all the receptions after this.
UART_IFReadData( ch, 1, &temp, &wReadSize ); // 1Byte transmission is need
}else{
// If there is room in the internal buffer,read data to the internal buffer directly
UART_IFReadData( ch, (unsigned short)(psRxInfo->wTempSize - psRxInfo->wRcvdSize), (psRxInfo->pTempBuf + psRxInfo->wRcvdSize), &wReadSize ); // 1Byte transmission is need
psRxInfo->wRcvdSize += wReadSize; // Update the number of data that transmitted.
}
}
}
}else{
// After the call of API, receives data.
//-----------------------------
if( psRxInfo->state == TRAN_STATE_CMP ){
// It received the data continuously though the callback was notified with API
// When interrupt enters in the multiple.
if( psRxInfo->wRcvdSize == 0 ){
// Receive for the first time
UART_IFReadData( ch, psRxInfo->wTempSize, psRxInfo->pTempBuf, &wReadSize ); // 1Byte transmission request
psRxInfo->wRcvdSize = wReadSize;
}else{
// Reception since the second times
if( psRxInfo->wRcvdSize >= psRxInfo->wTempSize ){
unsigned char temp;
// It changes the state because the internal buffer became full.
psRxInfo->state = TRAN_STATE_BUF_OVERFLOW;
// In the FIFO, delete all the receptions after this.
UART_IFReadData( ch, 1, &temp, &wReadSize ); // 1Byte transmission is need
}else{
// If there is room in the internal buffer,read data to the internal buffer directly
UART_IFReadData( ch, (unsigned short)(psRxInfo->wTempSize - psRxInfo->wRcvdSize), (psRxInfo->pTempBuf + psRxInfo->wRcvdSize), &wReadSize ); // 1Byte transmission is need
psRxInfo->wRcvdSize += wReadSize; // Update the number of data that transmitted.
}
}
return STATUS_SUCCESS;
}
// --- Check the status ---
if( wStatus != STATUS_SUCCESS ){
// Transmission error completion callback notification
if( psRxInfo->state == TRAN_STATE_EXEC_BINASYNC ){
if( psRxInfo->pfnCallback != NULL ){ // The callback is not notified if pCallbackProc is NULL.
sXferResult.bChannel = ch;
sXferResult.wReqSize = psRxInfo->wReqSize;
sXferResult.wActSize = psRxInfo->wActSize;
sXferResult.pBufAddr = psRxInfo->pReqAddr;
psRxInfo->state = TRAN_STATE_READY; // Waiting for transmission preparation
psRxInfo->pfnCallback( UART_FUNCM_RCV_DATA_CMP, wStatus, &sXferResult );
}
}else{
// TRAN_STATE_EXEC_SYNC
psRxInfo->state = TRAN_STATE_CMP; // The state is changed without callback at synchronization.
}
// Receive data update
return STATUS_SUCCESS;;
}
// Read the FIFO data
//----------------------------
wRxStatus = UART_IFReadData( ch, (unsigned short)(psRxInfo->wReqSize-psRxInfo->wActSize), psRxInfo->pPutAddr, &wReadSize );
if( wRxStatus != STATUS_SUCCESS ){
return STATUS_UNSUCCESSFUL;
}
psRxInfo->wActSize += wReadSize;
psRxInfo->pPutAddr += wReadSize;
if( psRxInfo->wActSize >= psRxInfo->wReqSize ){
// --- All data had been received. ---
// It processes according to the confirmation of the asynchronous or synchronous.
if( psRxInfo->state == TRAN_STATE_EXEC_BINASYNC ){
// --- Asynchronous ---
if( psRxInfo->pfnCallback != NULL ){ // The callback is not notified if pCallbackProc is NULL.
UART_FUNC_XFER_RESULT sXferResult;
sXferResult.bChannel = ch;
sXferResult.wReqSize = psRxInfo->wReqSize;
sXferResult.wActSize = psRxInfo->wActSize;
sXferResult.pBufAddr = psRxInfo->pReqAddr; // Address specified by API call
psRxInfo->state = TRAN_STATE_READY; // Waiting for transmission preparation
psRxInfo->pfnCallback( UART_FUNCM_RCV_DATA_CMP, STATUS_SUCCESS, &sXferResult );
}
}else{
// ---synchronous---
psRxInfo->state = TRAN_STATE_CMP; // The state is changed without callback at synchronization.
}
}
}
return STATUS_SUCCESS;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -