mirror of
https://gitee.com/Lamdonn/varch.git
synced 2026-04-30 19:09:14 +08:00
632 lines
21 KiB
C
632 lines
21 KiB
C
/*********************************************************************************************************
|
|
* ------------------------------------------------------------------------------------------------------
|
|
* file description
|
|
* ------------------------------------------------------------------------------------------------------
|
|
* \file icom.c
|
|
* \unit icom
|
|
* \brief This is a simple internal communication module for C language
|
|
* \author Lamdonn
|
|
* \version v0.1.0
|
|
* \license GPL-2.0
|
|
* \copyright Copyright (C) 2026 Lamdonn.
|
|
********************************************************************************************************/
|
|
#include "icom.h"
|
|
|
|
/**
|
|
* \brief: ICOM header field
|
|
* \note: This size is used to store the flag, transmit channel count, receive channel count, and data length of the channel
|
|
*/
|
|
|
|
#define ICOM_FLAG_SIZE (4) /**< ICOM flag size */
|
|
#define ICOM_TCNT_SIZE (4) /**< ICOM transmit channel count size */
|
|
#define ICOM_RCNT_SIZE (4) /**< ICOM receive channel count size */
|
|
#define ICOM_DLEN_SIZE (4) /**< ICOM data length size */
|
|
|
|
/**
|
|
* \brief: ICOM header field index
|
|
* \note: This index is used to access the flag, transmit channel count, receive channel count, and data length of the channel
|
|
*/
|
|
|
|
#define ICOM_FLAG_INDEX (0)
|
|
#define ICOM_TCNT_INDEX (ICOM_FLAG_INDEX + ICOM_FLAG_SIZE)
|
|
#define ICOM_RCNT_INDEX (ICOM_TCNT_INDEX + ICOM_TCNT_SIZE)
|
|
#define ICOM_DLEN_INDEX (ICOM_RCNT_INDEX + ICOM_RCNT_SIZE)
|
|
#define ICOM_DATA_INDEX (ICOM_DLEN_INDEX + ICOM_DLEN_SIZE)
|
|
|
|
/**
|
|
* \brief: ICOM header size
|
|
* \note:
|
|
* | Offset | Field | Size | Description |
|
|
* | :----: | :---: | :--: | :--------- |
|
|
* | 0 | Flag | 4 | Channel flag |
|
|
* | 4 | Tcnt | 4 | Transmit channel count |
|
|
* | 8 | Rcnt | 4 | Receive channel count |
|
|
* | 12 | Dlen | 4 | Data length |
|
|
*/
|
|
#define ICOM_HEAD_SIZE (ICOM_FLAG_SIZE + ICOM_TCNT_SIZE + ICOM_RCNT_SIZE + ICOM_DLEN_SIZE)
|
|
|
|
/**
|
|
* \brief: ICOM channel flag
|
|
* \note: This flag is used to indicate the status of the channel
|
|
*/
|
|
|
|
#define ICOM_F_INIT ((uint8_t)0x12) /**< ICOM channel flag: initialized */
|
|
#define ICOM_F_BUSY ((uint8_t)0x34) /**< ICOM channel flag: busy */
|
|
#define ICOM_F_IDLE ((uint8_t)0x56) /**< ICOM channel flag: idle */
|
|
#define ICOM_F_ERROR ((uint8_t)0x78) /**< ICOM channel flag: error */
|
|
|
|
#define getTxBase(i) (icom->txconfig[i].base) /**< ICOM transmit channel base address */
|
|
#define getTxSize(i) (icom->txconfig[i].size) /**< ICOM transmit channel size */
|
|
#define getTxFlag(i) (getTxBase(i)[ICOM_FLAG_INDEX]) /**< ICOM transmit channel flag */
|
|
#define getTxDlen(i) (getTxBase(i)[ICOM_DLEN_INDEX]) /**< ICOM transmit channel data length */
|
|
#define getTxData(i) (getTxBase(i)[ICOM_DATA_INDEX]) /**< ICOM transmit channel data */
|
|
#define getTxTcnt(i) (getTxBase(i)[ICOM_TCNT_INDEX]) /**< ICOM transmit channel count */
|
|
#define getTxRcnt(i) (getTxBase(i)[ICOM_RCNT_INDEX]) /**< ICOM transmit channel receive count */
|
|
|
|
#define getRxBase(i) (icom->rxconfig[i].base) /**< ICOM receive channel base address */
|
|
#define getRxSize(i) (icom->rxconfig[i].size) /**< ICOM receive channel size */
|
|
#define getRxFlag(i) (getRxBase(i)[ICOM_FLAG_INDEX]) /**< ICOM receive channel flag */
|
|
#define getRxDlen(i) (getRxBase(i)[ICOM_DLEN_INDEX]) /**< ICOM receive channel data length */
|
|
#define getRxData(i) (getRxBase(i)[ICOM_DATA_INDEX]) /**< ICOM receive channel data */
|
|
#define getRxTcnt(i) (getRxBase(i)[ICOM_TCNT_INDEX]) /**< ICOM receive channel count */
|
|
#define getRxRcnt(i) (getRxBase(i)[ICOM_RCNT_INDEX]) /**< ICOM receive channel receive count */
|
|
|
|
#define getTxPrivate(i) (icom->txconfig[i].private) /**< ICOM transmit channel private data */
|
|
#define getRxPrivate(i) (icom->rxconfig[i].private) /**< ICOM receive channel private data */
|
|
#define getPrivateOnline(p) ((p)[0]) /**< ICOM private data: online */
|
|
#define getPrivateOffCnt(p) ((p)[1]) /**< ICOM private data: offline count */
|
|
#define getPrivatePCount(p) ((p)[2]) /**< ICOM private data: process count */
|
|
#define getPrivateCCount(p) ((p)[3]) /**< ICOM private data: complete count */
|
|
|
|
/**
|
|
* \brief: ICOM cache invalidate function
|
|
* \param addr: Cache address
|
|
* \param size: Cache size
|
|
*/
|
|
#define Cache_Inv(addr, size) do { if (icom->inv) (icom->inv)((addr), (size)); } while (0)
|
|
|
|
/**
|
|
* \brief: ICOM cache write-back invalidate function
|
|
* \param addr: Cache address
|
|
* \param size: Cache size
|
|
*/
|
|
#define Cache_wbInv(addr, size) do { if (icom->wbinv) (icom->wbinv)((addr), (size)); } while (0)
|
|
|
|
/**
|
|
* \brief: ICOM transmitter ready function
|
|
* \param icom: ICOM handle
|
|
* \param channel: Channel number
|
|
* \return: 1 means ready, 0 means not ready
|
|
*/
|
|
static int icom_transmitter_ready(ICOM *icom, uint16_t channel)
|
|
{
|
|
int ret = 0;
|
|
Cache_Inv(&getRxFlag(channel), ICOM_FLAG_SIZE);
|
|
switch (getRxFlag(channel))
|
|
{
|
|
case ICOM_F_INIT:
|
|
{
|
|
getRxFlag(channel) = ICOM_F_IDLE;
|
|
Cache_wbInv(&getRxFlag(channel), ICOM_FLAG_SIZE);
|
|
ret = 1;
|
|
} break;
|
|
case ICOM_F_IDLE:
|
|
case ICOM_F_BUSY:
|
|
{
|
|
ret = 1;
|
|
} break;
|
|
default:
|
|
{
|
|
ret = 0;
|
|
} break;
|
|
}
|
|
return ret;
|
|
}
|
|
|
|
/**
|
|
* \brief: ICOM set data length function
|
|
* \param icom: ICOM handle
|
|
* \param channel: Channel number
|
|
* \param length: Data length
|
|
*/
|
|
static void icom_set_data_length(ICOM *icom, uint16_t channel, uint32_t length)
|
|
{
|
|
/* Data length is stored in little-endian format */
|
|
getTxBase(channel)[ICOM_DLEN_INDEX] = length & 0xFF;
|
|
getTxBase(channel)[ICOM_DLEN_INDEX + 1] = (length >> 8) & 0xFF;
|
|
getTxBase(channel)[ICOM_DLEN_INDEX + 2] = (length >> 16) & 0xFF;
|
|
getTxBase(channel)[ICOM_DLEN_INDEX + 3] = (length >> 24) & 0xFF;
|
|
Cache_wbInv(&(getTxBase(channel)[ICOM_DLEN_INDEX]), ICOM_DLEN_SIZE);
|
|
}
|
|
|
|
/**
|
|
* \brief: ICOM get data length function
|
|
* \param icom: ICOM handle
|
|
* \param channel: Channel number
|
|
* \return: Data length
|
|
*/
|
|
static uint32_t icom_get_data_length(ICOM *icom, uint16_t channel)
|
|
{
|
|
uint32_t length = 0;
|
|
Cache_Inv(&(getRxBase(channel)[ICOM_DLEN_INDEX]), ICOM_DLEN_SIZE);
|
|
/* Data length is stored in little-endian format */
|
|
length = (uint32_t)((getRxBase(channel)[ICOM_DLEN_INDEX]) |
|
|
(getRxBase(channel)[ICOM_DLEN_INDEX + 1] << 8) |
|
|
(getRxBase(channel)[ICOM_DLEN_INDEX + 2] << 16) |
|
|
(getRxBase(channel)[ICOM_DLEN_INDEX + 3] << 24));
|
|
return length;
|
|
}
|
|
|
|
/**
|
|
* \brief: ICOM control online function
|
|
* \param icom: ICOM handle
|
|
* \param private: Private data
|
|
* \param count: Process count
|
|
* \note: If process count is equal to complete count, then set online to 1.
|
|
* If offline count is less than 5, then set offline count to 1.
|
|
* Otherwise, set online to 0.
|
|
* If online is 1, then set offline count to 0.
|
|
* If offline count is greater than 5, then set online to 0.
|
|
*/
|
|
static void icom_control_online(ICOM *icom, uint32_t *private, uint32_t count)
|
|
{
|
|
getPrivateCCount(private) = count;
|
|
if (getPrivateCCount(private) == getPrivatePCount(private))
|
|
{
|
|
if (getPrivateOffCnt(private) <= 5)
|
|
{
|
|
getPrivateOffCnt(private)++;
|
|
}
|
|
/* If offline count is greater than 5, then set online to 0 */
|
|
else
|
|
{
|
|
getPrivateOnline(private) = 0;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
getPrivateOnline(private) = 1;
|
|
getPrivateOffCnt(private) = 0;
|
|
}
|
|
getPrivatePCount(private) = getPrivateCCount(private);
|
|
}
|
|
|
|
/**
|
|
* \brief: ICOM online handle function
|
|
* \param icom: ICOM handle
|
|
* \note: If online is 1, then increment transmitter count.
|
|
* If offline count is greater than 5, then set online to 0.
|
|
*/
|
|
static void icom_online_handle(ICOM *icom)
|
|
{
|
|
uint16_t channel;
|
|
|
|
/* Handle tx channal */
|
|
if (icom->txconfig && icom->txcount > 0)
|
|
{
|
|
for (channel = 0; channel < icom->txcount; channel++)
|
|
{
|
|
Cache_Inv(&getTxTcnt(channel), ICOM_TCNT_SIZE);
|
|
/* Increase tx count to indicate tx channal is online */
|
|
(*((uint32_t *)(&getTxTcnt(channel))))++;
|
|
Cache_wbInv(&getTxTcnt(channel), ICOM_TCNT_SIZE);
|
|
Cache_Inv(&getTxRcnt(channel), ICOM_RCNT_SIZE);
|
|
/* Control online status */
|
|
icom_control_online(icom, getTxPrivate(channel), (*((uint32_t *)&getTxRcnt(channel))));
|
|
}
|
|
}
|
|
|
|
/* Handle rx channal */
|
|
if (icom->rxconfig && icom->rxcount > 0)
|
|
{
|
|
for (channel = 0; channel < icom->rxcount; channel++)
|
|
{
|
|
Cache_Inv(&getRxRcnt(channel), ICOM_RCNT_SIZE);
|
|
/* Increase rx count to indicate rx channal is online */
|
|
(*((uint32_t *)(&getRxRcnt(channel))))++;
|
|
Cache_wbInv(&getRxRcnt(channel), ICOM_RCNT_SIZE);
|
|
Cache_Inv(&getRxTcnt(channel), ICOM_TCNT_SIZE);
|
|
/* Control online status */
|
|
icom_control_online(icom, getRxPrivate(channel), (*((uint32_t *)&getRxTcnt(channel))));
|
|
}
|
|
}
|
|
}
|
|
|
|
/**
|
|
* \brief: ICOM rxdata handle function
|
|
* \param icom: ICOM handle
|
|
* \note: If rx channal is ready, then check data length.
|
|
* If data length is valid, then call callback function.
|
|
* Otherwise, set rx channal to idle.
|
|
*/
|
|
static void icom_rxdata_handle(ICOM *icom)
|
|
{
|
|
uint16_t channel;
|
|
uint32_t length = 0;
|
|
|
|
/* Handle Rx */
|
|
if (icom->rxconfig && icom->rxcount > 0)
|
|
{
|
|
for (channel = 0; channel < icom->rxcount; channel++)
|
|
{
|
|
/* Check rx channal is ready */
|
|
if (icom_transmitter_ready(icom, channel))
|
|
{
|
|
Cache_Inv(&getRxFlag(channel), ICOM_FLAG_SIZE);
|
|
/* Check rx channal is busy.
|
|
* Indicate that rx channal is ready to receive data.
|
|
*/
|
|
if (getRxFlag(channel) == ICOM_F_BUSY)
|
|
{
|
|
/* Get data length and check data length is valid */
|
|
length = icom_get_data_length(icom, channel);
|
|
if (length <= getRxSize(channel) - ICOM_HEAD_SIZE)
|
|
{
|
|
/* Call callback function */
|
|
if (icom->rxconfig[channel].callback)
|
|
{
|
|
Cache_Inv(&getRxData(channel), length);
|
|
icom->rxconfig[channel].callback(channel, &getRxData(channel), length);
|
|
/* Set rx channal to idle */
|
|
getRxFlag(channel) = ICOM_F_IDLE;
|
|
Cache_wbInv(&getRxFlag(channel), ICOM_FLAG_SIZE);
|
|
}
|
|
else /* Receive manual */
|
|
{
|
|
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
/**
|
|
* \brief: ICOM initialize function
|
|
* \param icom: ICOM handle
|
|
* \return: ICOM error code
|
|
*/
|
|
int icom_init(ICOM *icom)
|
|
{
|
|
uint16_t channel;
|
|
|
|
/* Input value validity check */
|
|
if (!icom) return ICOM_E_IHANDLE;
|
|
if (icom->init) return ICOM_E_OK;
|
|
|
|
/* Initialize tx channal */
|
|
if (icom->txconfig && icom->txcount > 0)
|
|
{
|
|
for (channel = 0; channel < icom->txcount; channel++)
|
|
{
|
|
if (getTxBase(channel) != NULL)
|
|
{
|
|
/* Initialize tx channal flag */
|
|
getTxFlag(channel) = ICOM_F_INIT;
|
|
Cache_wbInv(&getTxFlag(channel), ICOM_FLAG_SIZE);
|
|
}
|
|
|
|
/* Initialize tx channal private data */
|
|
memset(getTxPrivate(channel), 0, sizeof(getTxPrivate(channel)));
|
|
|
|
/* Initialize tx channal callback function, default is NULL */
|
|
icom->txconfig[channel].callback = NULL;
|
|
}
|
|
}
|
|
|
|
/* Initialize rx channal */
|
|
if (icom->rxconfig && icom->rxcount > 0)
|
|
{
|
|
for (channel = 0; channel < icom->rxcount; channel++)
|
|
{
|
|
if (getRxBase(channel) != NULL)
|
|
{
|
|
/* Initialize rx channal flag */
|
|
icom_transmitter_ready(icom, channel);
|
|
}
|
|
|
|
/* Initialize rx channal private data */
|
|
memset(getRxPrivate(channel), 0, sizeof(getRxPrivate(channel)));
|
|
}
|
|
}
|
|
|
|
/* ICOM controller hs been initialized. */
|
|
icom->init = 1;
|
|
|
|
return ICOM_E_OK;
|
|
}
|
|
|
|
/**
|
|
* \brief: ICOM task function
|
|
* \param icom: ICOM handle
|
|
* \return: ICOM error code
|
|
*/
|
|
int icom_task(ICOM *icom)
|
|
{
|
|
/* Input value validity check */
|
|
if (!icom) return ICOM_E_IHANDLE;
|
|
if (!icom->init) return ICOM_E_NINIT;
|
|
|
|
/* Handle online status */
|
|
icom_online_handle(icom);
|
|
/* Handle rxdata */
|
|
icom_rxdata_handle(icom);
|
|
|
|
return ICOM_E_OK;
|
|
}
|
|
|
|
/**
|
|
* \brief: ICOM transmit getbuffer function
|
|
* \param icom: ICOM handle
|
|
* \param channel: Transmit channal index
|
|
* \param buffer: Pointer to store data buffer
|
|
* \param length: Pointer to store data length
|
|
* \return: ICOM error code
|
|
*/
|
|
int icom_transmit_getbuffer(ICOM *icom, uint16_t channel, uint8_t **buffer, uint32_t *length)
|
|
{
|
|
/* Input value validity check */
|
|
if (!icom) return ICOM_E_IHANDLE;
|
|
if (!icom->init) return ICOM_E_NINIT;
|
|
if (channel >= icom->txcount) return ICOM_E_IOUT;
|
|
if (!getTxBase(channel)) return ICOM_E_NBASE;
|
|
if (!buffer) return ICOM_E_IBUFFER;
|
|
|
|
/* Get transmit buffer */
|
|
*buffer = &getTxData(channel);
|
|
|
|
/* Get data length */
|
|
if (length) *length = getTxSize(channel) - ICOM_HEAD_SIZE;
|
|
|
|
return ICOM_E_OK;
|
|
}
|
|
|
|
/**
|
|
* \brief: ICOM transmit trigger function
|
|
* \param icom: ICOM handle
|
|
* \param channel: Transmit channal index
|
|
* \param length: Data length
|
|
* \note: Data length must be less than or equal to the transmit buffer size minus ICOM_HEAD_SIZE
|
|
* \return: ICOM error code
|
|
*/
|
|
int icom_transmit_trigger(ICOM *icom, uint16_t channel, uint32_t length)
|
|
{
|
|
/* Input value validity check */
|
|
if (!icom) return ICOM_E_IHANDLE;
|
|
if (!icom->init) return ICOM_E_NINIT;
|
|
if (channel >= icom->txcount) return ICOM_E_IOUT;
|
|
if (!getTxBase(channel)) return ICOM_E_NBASE;
|
|
if (length + ICOM_HEAD_SIZE > getTxSize(channel)) return ICOM_E_LOUT;
|
|
if (getTxFlag(channel) != ICOM_F_IDLE) return ICOM_E_BUSY;
|
|
|
|
/* Set data length */
|
|
icom_set_data_length(icom, channel, length);
|
|
/* Set tx channal to busy, need rx object receive data and set to ICOM_F_IDLE */
|
|
getTxFlag(channel) = ICOM_F_BUSY;
|
|
Cache_wbInv(&getTxFlag(channel), ICOM_FLAG_SIZE);
|
|
|
|
return ICOM_E_OK;
|
|
}
|
|
|
|
/**
|
|
* \brief: ICOM transmit function
|
|
* \param icom: ICOM handle
|
|
* \param channel: Transmit channal index
|
|
* \param data: Pointer to data buffer
|
|
* \param length: Data length
|
|
* \note: Data length must be less than or equal to the transmit buffer size minus ICOM_HEAD_SIZE
|
|
* \return: ICOM error code
|
|
*/
|
|
int icom_transmit(ICOM *icom, uint16_t channel, uint8_t *data, uint32_t length)
|
|
{
|
|
int ret = ICOM_E_OK;
|
|
uint8_t *buffer = NULL;
|
|
uint32_t blength = 0;
|
|
uint32_t i = 0;
|
|
|
|
/* Get transmit buffer */
|
|
ret = icom_transmit_getbuffer(icom, channel, &buffer, &blength);
|
|
if (ICOM_E_OK != ret) return ret;
|
|
if (length > blength) return ICOM_E_LOUT;
|
|
|
|
/* Copy data to transmit buffer */
|
|
for (i = 0; i < length; i++)
|
|
{
|
|
buffer[i] = data[i];
|
|
}
|
|
Cache_wbInv(buffer, length);
|
|
|
|
/* Trigger transmit */
|
|
ret = icom_transmit_trigger(icom, channel, length);
|
|
|
|
return ret;
|
|
}
|
|
|
|
/**
|
|
* \brief: ICOM receive getbuffer function
|
|
* \param icom: ICOM handle
|
|
* \param channel: Receive channal index
|
|
* \param buffer: Pointer to store data buffer
|
|
* \param length: Pointer to store data length
|
|
* \return: ICOM error code
|
|
*/
|
|
int icom_receive_getbuffer(ICOM *icom, uint16_t channel, uint8_t **buffer, uint32_t *length)
|
|
{
|
|
if (!icom) return ICOM_E_IHANDLE;
|
|
if (!icom->init) return ICOM_E_NINIT;
|
|
if (channel >= icom->txcount) return ICOM_E_IOUT;
|
|
if (!getRxBase(channel)) return ICOM_E_NBASE;
|
|
if (!buffer) return ICOM_E_IBUFFER;
|
|
|
|
*buffer = &getRxData(channel);
|
|
|
|
if (length) *length = getRxSize(channel) - ICOM_HEAD_SIZE;
|
|
|
|
return ICOM_E_OK;
|
|
}
|
|
|
|
/**
|
|
* \brief: ICOM receive indicate function
|
|
* \param icom: ICOM handle
|
|
* \param channel: Receive channal index
|
|
* \param length: Pointer to store data length
|
|
* \return: ICOM error code
|
|
*/
|
|
int icom_receive_indicate(ICOM *icom, uint16_t channel, uint32_t *length)
|
|
{
|
|
/* Input value validity check */
|
|
if (!icom) return ICOM_E_IHANDLE;
|
|
if (!icom->init) return ICOM_E_NINIT;
|
|
if (channel >= icom->rxcount) return ICOM_E_IOUT;
|
|
if (!getRxBase(channel)) return ICOM_E_NBASE;
|
|
|
|
/* Check if the rx channal is ready */
|
|
if (icom_transmitter_ready(icom, channel))
|
|
{
|
|
Cache_Inv(&getRxFlag(channel), ICOM_FLAG_SIZE);
|
|
if (getRxFlag(channel) == ICOM_F_BUSY)
|
|
{
|
|
/* Get data length */
|
|
if (length) *length = icom_get_data_length(icom, channel);
|
|
}
|
|
else
|
|
{
|
|
return ICOM_E_NRECEIVE;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
return ICOM_E_NRECEIVE;
|
|
}
|
|
|
|
return ICOM_E_OK;
|
|
}
|
|
|
|
/**
|
|
* \brief: ICOM receive end function
|
|
* \param icom: ICOM handle
|
|
* \param channel: Receive channal index
|
|
* \return: ICOM error code
|
|
*/
|
|
int icom_receive_end(ICOM *icom, uint16_t channel)
|
|
{
|
|
/* Input value validity check */
|
|
if (!icom) return ICOM_E_IHANDLE;
|
|
if (!icom->init) return ICOM_E_NINIT;
|
|
if (channel >= icom->rxcount) return ICOM_E_IOUT;
|
|
|
|
/* Check if the rx channal is ready */
|
|
if (icom_transmitter_ready(icom, channel))
|
|
{
|
|
Cache_Inv(&getRxFlag(channel), ICOM_FLAG_SIZE);
|
|
if (getRxFlag(channel) == ICOM_F_BUSY)
|
|
{
|
|
/* Set rx channal to idle */
|
|
getRxFlag(channel) = ICOM_F_IDLE;
|
|
}
|
|
else
|
|
{
|
|
return ICOM_E_NRECEIVE;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
return ICOM_E_NRECEIVE;
|
|
}
|
|
|
|
return ICOM_E_OK;
|
|
}
|
|
|
|
/**
|
|
* \brief: ICOM receive function
|
|
* \param icom: ICOM handle
|
|
* \param channel: Receive channal index
|
|
* \param data: Pointer to data buffer
|
|
* \param length: Pointer to store data length
|
|
* \note: Data length must be less than or equal to the receive buffer size minus ICOM_HEAD_SIZE
|
|
* \return: ICOM error code
|
|
*/
|
|
int icom_receive(ICOM *icom, uint16_t channel, uint8_t *data, uint32_t *length)
|
|
{
|
|
int ret = ICOM_E_OK;
|
|
uint8_t *buffer = NULL;
|
|
uint32_t rxlength = 0;
|
|
uint32_t blength = 0;
|
|
uint32_t ilength = 0;
|
|
uint32_t i = 0;
|
|
|
|
/* Input value validity check */
|
|
if (!icom) return ICOM_E_IHANDLE;
|
|
if (!icom->init) return ICOM_E_NINIT;
|
|
if (channel >= icom->rxcount) return ICOM_E_IOUT;
|
|
if (!getRxBase(channel)) return ICOM_E_NBASE;
|
|
if (!data) return ICOM_E_IBUFFER;
|
|
|
|
if (!length) return ICOM_E_ILENGTH;
|
|
ilength = *length;
|
|
|
|
/* Determine if there is any data to receive */
|
|
ret = icom_receive_indicate(icom, channel, &rxlength);
|
|
if (ICOM_E_OK != ret) return ret;
|
|
|
|
/* Get receive buffer */
|
|
ret = icom_receive_getbuffer(icom, channel, &buffer, &blength);
|
|
if (ICOM_E_OK != ret) return ret;
|
|
|
|
if (rxlength > blength) return ICOM_E_LOUT;
|
|
|
|
/* Copy data from receive buffer */
|
|
for (i = 0; i < rxlength; i++)
|
|
{
|
|
data[i] = buffer[i];
|
|
}
|
|
|
|
/* End receive */
|
|
icom_receive_end(icom, channel);
|
|
|
|
*length = rxlength;
|
|
|
|
return ICOM_E_OK;
|
|
}
|
|
|
|
/**
|
|
* \brief: ICOM transmit channal online check function
|
|
* \param icom: ICOM handle
|
|
* \param channel: Transmit channal index
|
|
* \param online: Pointer to store online status
|
|
* \return: ICOM error code
|
|
*/
|
|
int icom_txchannel_online(ICOM *icom, uint16_t channel, uint8_t *online)
|
|
{
|
|
if (!icom) return ICOM_E_IHANDLE;
|
|
if (!icom->init) return ICOM_E_NINIT;
|
|
if (channel >= icom->txcount) return ICOM_E_IOUT;
|
|
if (!online) return ICOM_E_IBUFFER;
|
|
|
|
*online = getPrivateOnline(getTxPrivate(channel));
|
|
|
|
return ICOM_E_OK;
|
|
}
|
|
|
|
/**
|
|
* \brief: ICOM receive channal online check function
|
|
* \param icom: ICOM handle
|
|
* \param channel: Receive channal index
|
|
* \param online: Pointer to store online status
|
|
* \return: ICOM error code
|
|
*/
|
|
int icom_rxchannel_online(ICOM *icom, uint16_t channel, uint8_t *online)
|
|
{
|
|
if (!icom) return ICOM_E_IHANDLE;
|
|
if (!icom->init) return ICOM_E_NINIT;
|
|
if (channel >= icom->rxcount) return ICOM_E_IOUT;
|
|
if (!online) return ICOM_E_IBUFFER;
|
|
|
|
*online = getPrivateOnline(getRxPrivate(channel));
|
|
|
|
return ICOM_E_OK;
|
|
}
|
|
|
|
|