Initial version.

This commit is contained in:
Gatsby Van
2023-12-20 00:11:03 +08:00
commit 416bd53733
1043 changed files with 293547 additions and 0 deletions
+468
View File
@@ -0,0 +1,468 @@
/*****************************************************************************/
/**
* Description: System bus protocol implementation file.
*
* Date: 2023-05-06 10:13
* Last Edit Time: [2023-05-06 21:45]
*
* Revisions: Rev 0.0
* History:
* [2023-05-06]: Initial version.
* [2023-09-13]: Update to 485 portocol-20220816
*
* Copyright(c) 2021 Beijing Institute of Technology.
* Lab of Communication and Network
*
******************************************************************************/
/***************************** Include Files *********************************/
#include <stdlib.h>
#include <string.h>
#include <stdint.h>
#include <stdbool.h>
#include "systembus_uart.h"
#include "systembus.h"
#include "util.h"
#include "common.h"
#include "error.h"
#include "circ_queue.h"
#include "../system_monitor.h"
// Common Field
// -- Command word
#define WD_CMD 0x00
// -- Production type
#define WD_PRD 0x01
#define PRD_DL_K 0xDD
#define PRD_DL_S 0xDE
#define PRD_ALL 0xFF
// Self-Test
#define CMD_SELF_TEST 0xE1
// -- Request
// -- -- --
// -- Response
// -- -- Self-Test Result
#define ST_RSP_LEN 16
#define WD_ST_RET 0x02
#define ST_RET_OK 0xAA
#define ST_RET_ERROR 0x55
// -- -- Signal processor voltage
#define WD_SP_VOLT_L 0x03
#define WD_SP_VOLT_H 0x04
// -- -- Signal processor temperature
#define WD_SP_TEMP_L 0x05
#define WD_SP_TEMP_H 0x06
// -- -- Signal processor chip status
#define WD_SP_CS_L 0x07
#define WD_SP_CS_H 0x08
// -- -- Signal processor antenna voltage
#define WD_AS_VOLT 0x09
// -- -- Signal processor antenna temperature
#define WD_AS_TEMP 0x0A
// -- -- Signal processor antenna PLL lock status
#define WD_AS_PLL 0x0B
// -- -- Signal processor antenna MGC
#define WD_AS_MGC_L 0x0C
#define WD_AS_MGC_H 0x0D
// -- -- Signal processor antenna status
#define WD_AS_ST 0x0E.
// -- -- Dummy must be 0x00
#define WD_ST_DUMMY 0x0F
// Data Send Test Command
#define CMD_DATA_TEST_A 0xE2
// -- Request
#define DATA_TEST_REQ_A_LEN 80
// -- -- 78 byte payload
// -- Response
#define DATA_TEST_RSP_A_LEN 80
// -- -- 78 byte payload
// Data Send Test Command
#define CMD_DATA_TEST_B 0xF2
// -- Request
#define DATA_TEST_REQ_B_LEN 152
// -- -- 150 byte payload
// -- Response
#define DATA_TEST_RSP_B_LEN 152
// -- -- 150 byte payload
// Config load
#define CMD_CONFIG 0xE3
// -- Request
#define WD_EN_CMD 0x02
#define EN_CMD_ON 0x66
#define WD_MODE_CMD 0x03
#define MODE_CMD_HEAD 0x11
#define MODE_CMD_MEMBER 0x11
// -- Response
// -- -- none response
// System info update
#define CMD_SYS_INFO 0x33
// -- Request
// -- -- 54 byte system info
// -- Response
// -- -- none response
// Data Send Test Command
#define CMD_FLJ_SEND 0xE4
// -- Request
// -- -- 78 byte payload
// -- Response
// -- -- none response
// Data Send Test Command
#define CMD_LJ_SEND 0xF4
// -- Request
// -- -- 156 byte payload
// -- Response
// -- -- none response
// FLJ Poll
#define CMD_FLJ_POLL 0xE5
// -- Request
#define WD_FLJ_POLL 0x02
#define FLJ_POLL_CODE 0x77
// -- Response
#define FLJ_POLL_RESP_LEN 78
// -- -- received 78 byte payload
// LJ Poll
#define CMD_LJ_POLL 0xF5
// -- Request
#define WD_LJ_POLL 0x02
#define LJ_POLL_CODE 0x77
// -- Response
#define LJ_POLL_RESP_LEN 156
// -- -- received 156 byte payload
// Remote Test
#define CMD_RM_TEST 0xE6
// -- Request
// -- -- none, response with roll call (after roll call resp)
// -- Response
#define RM_TEST_LEN 210
// -- -- received 208 byte Remote Test infomation
// My Production Type
#define MY_PRD_ID PRD_DL_K
inline bool SystemBus_IsReqPendding(SYSBUS *instPtr){
ASSERT(instPtr != NULL);
return (!isCircQueueEmpty(instPtr->rxQueue));
}
inline bool SystemBus_IsRsqPendding(SYSBUS *instPtr){
ASSERT(instPtr != NULL);
return (!isCircQueueEmpty(instPtr->txQueue));
}
inline bool SystemBus_IsTxBusy(SYSBUS *instPtr) {
ASSERT(instPtr != NULL);
return (!instPtr->isTxDone);
}
inline bool SystemBus_IsRxBusy(SYSBUS *instPtr) {
ASSERT(instPtr != NULL);
return SysbusUart_IsRxBusy(instPtr->uartInst);
}
/*****************************************************************************/
/**
* @brief Initialize System Bus instance.
*
* @param InstPtr A double pointer to System Bus instance.
* @param config A pointer to System Bus configurations.
*
* @return None.
*
******************************************************************************/
int32_t SystemBus_Init(SYSBUS **instPtr, SYSBUS_CONFIG *config) {
ASSERT(instPtr != NULL);
ASSERT(config != NULL);
SYSBUS_UART_CONFIG uartConfig;
int32_t Status;
(*instPtr) = malloc(sizeof(SYSBUS));
if ((*instPtr) == NULL) {
return FAILURE;
}
(*instPtr)->rxQueue = NULL;
(*instPtr)->txQueue = NULL;
(*instPtr)->uartInst = NULL;
memcpy(&((*instPtr)->config), config, sizeof(SYSBUS_CONFIG));
uartConfig.baseAddr = config->baseAddr;
Status = SysbusUart_Init(&((*instPtr)->uartInst), &uartConfig);
if (Status != SUCCESS) {
Status = ENOMEM;
goto sysbus_init_error;
}
if(CircQueueCreate(&((*instPtr)->txQueue), (*instPtr)->config.txQueueMax) == false){
Status = ENOMEM;
goto sysbus_init_error;
}
if(CircQueueCreate(&((*instPtr)->rxQueue), (*instPtr)->config.rxQueueMax) == false){
Status = ENOMEM;
goto sysbus_init_error;
}
(*instPtr)->isRxDone = false; // nothing received.
(*instPtr)->isTxDone = true; // nothing to be sent.
return SUCCESS;
sysbus_init_error:
free((*instPtr)->uartInst);
free((*instPtr)->txQueue);
free((*instPtr)->rxQueue);
free(*instPtr);
return Status;
}
/*****************************************************************************/
/**
* @brief A handler function. This handler evaluate the message from system
* bus receive queue, and make appropriate response.
*
* @param instPtr A pointer to System Bus instance.
*
* @return None
*
******************************************************************************/
int32_t SystemBus_HandleCmd(SYSBUS* instPtr) {
ASSERT(instPtr != NULL);
int32_t Status;
SYSBUS_UART_FRAME *sysbusReq, *sysbusRsp;
uint8_t *data;
if (CircQueuePop(instPtr->rxQueue, (void**)(&sysbusReq)) == false) {
DBG_WARNING("SystemBus::Nothing to be handled.\n");
return EIGNORE;
}
data = sysbusReq->data;
if(data[WD_PRD] != MY_PRD_ID && data[WD_PRD] != PRD_ALL) {
DBG_WARNING("SystemBus::Production code mismatch!\n");
return EIGNORE;
}
switch(data[WD_CMD]){
case CMD_SELF_TEST : {
sysbusRsp = malloc(sizeof(SYSBUS_UART_FRAME));
sysbusRsp->len = ST_RSP_LEN;
memset(sysbusRsp->data,0x00,ST_RSP_LEN);
sysbusRsp->data[WD_CMD] = CMD_SELF_TEST;
sysbusRsp->data[WD_PRD] = MY_PRD_ID;
// FIXME: run self-test and insert result
sysbusRsp->data[WD_ST_RET] = ST_RET_OK;
if (CircQueuePush(instPtr->txQueue, (void *)sysbusRsp) == false){
DBG_WARNING("SystemBus::TX Queue overflowed!\n");
Status = EQUEUE;
break;
}
Status = SUCCESS;
break;
}
case CMD_DATA_TEST_A : {
sysbusRsp = malloc(sizeof(SYSBUS_UART_FRAME));
sysbusRsp->len = DATA_TEST_RSP_A_LEN;
memcpy(sysbusRsp->data, sysbusReq->data, DATA_TEST_RSP_A_LEN);
if (CircQueuePush(instPtr->txQueue, (void *)sysbusRsp) == false){
DBG_WARNING("SystemBus::TX Queue overflowed!\n");
Status = EQUEUE;
break;
}
Status = SUCCESS;
break;
}
case CMD_DATA_TEST_B : {
sysbusRsp = malloc(sizeof(SYSBUS_UART_FRAME));
sysbusRsp->len = DATA_TEST_RSP_B_LEN;
memcpy(sysbusRsp->data, sysbusReq->data, DATA_TEST_RSP_B_LEN);
if (CircQueuePush(instPtr->txQueue, (void *)sysbusRsp) == false){
DBG_WARNING("SystemBus::TX Queue overflowed!\n");
Status = EQUEUE;
break;
}
Status = SUCCESS;
break;
}
case CMD_CONFIG : {
// FIXME: apply configurations
// Power + Mode
// -- No response
_nop_(); // for debug
Status = SUCCESS;
break;
}
case CMD_SYS_INFO : {
SysMonitor_UpdateSysinfoRaw(data+2);
Status = SUCCESS;
break;
}
// TODO
case CMD_FLJ_SEND : {
SysMonitor_UpdateSendPayloadFLJRaw(data+2); // ommit 2 bytes control info
break;
}
case CMD_LJ_SEND : {
SysMonitor_UpdateSendPayloadLJRaw(data+2); // ommit 2 bytes control info
break;
}
case CMD_FLJ_POLL : {
if (data[WD_FLJ_POLL] != FLJ_POLL_CODE) {
DBG_WARNING("SystemBus::Invalid roll call code!\n");
Status = EIGNORE;
break;
}
sysbusRsp = malloc(sizeof(SYSBUS_UART_FRAME));
sysbusRsp->len = FLJ_POLL_RESP_LEN;
sysbusRsp->data[WD_CMD] = WD_FLJ_POLL;
sysbusRsp->data[WD_PRD] = MY_PRD_ID;
SysMonitor_GetRecvPayloadFLJRaw(sysbusRsp->data + 2); // ommit 2 bytes control info
if (CircQueuePush(instPtr->txQueue, (void *)sysbusRsp) == false){
DBG_WARNING("SystemBus::TX Queue overflowed!\n");
Status = EQUEUE;
break;
}
//FIXME: Confirm
// sysbusRsp = malloc(sizeof(SYSBUS_UART_FRAME));
// sysbusRsp->len = RM_TEST_LEN;
// sysbusRsp->data[WD_CMD] = CMD_RM_TEST;
// sysbusRsp->data[WD_PRD] = MY_PRD_ID;
// SysMonitor_GetSyslogRaw(sysbusRsp->data + 2); //ommit 2 bytes control info
// if (CircQueuePush(instPtr->txQueue, (void *)sysbusRsp) == false){
// DBG_WARNING("SystemBus::TX Queue overflowed!\n");
// Status = EQUEUE;
// break;
// }
Status = SUCCESS;
break;
}
case CMD_LJ_POLL : {
if (data[WD_LJ_POLL] != LJ_POLL_CODE) {
DBG_WARNING("SystemBus::Invalid roll call code!\n");
Status = EIGNORE;
break;
}
sysbusRsp = malloc(sizeof(SYSBUS_UART_FRAME));
sysbusRsp->len = LJ_POLL_RESP_LEN;
sysbusRsp->data[WD_CMD] = WD_LJ_POLL;
sysbusRsp->data[WD_PRD] = MY_PRD_ID;
SysMonitor_GetRecvPayloadLJRaw(sysbusRsp->data + 2); // ommit 2 bytes control info
if (CircQueuePush(instPtr->txQueue, (void *)sysbusRsp) == false){
DBG_WARNING("SystemBus::TX Queue overflowed!\n");
Status = EQUEUE;
break;
}
//FIXME: Confirm
// sysbusRsp = malloc(sizeof(SYSBUS_UART_FRAME));
// sysbusRsp->len = RM_TEST_LEN;
// sysbusRsp->data[WD_CMD] = CMD_RM_TEST;
// sysbusRsp->data[WD_PRD] = MY_PRD_ID;
// SysMonitor_GetSyslogRaw(sysbusRsp->data + 2); //ommit 2 bytes control info
// if (CircQueuePush(instPtr->txQueue, (void *)sysbusRsp) == false){
// DBG_WARNING("SystemBus::TX Queue overflowed!\n");
// Status = EQUEUE;
// break;
// }
Status = SUCCESS;
break;
}
default:{
DBG_ERROR("SystemBus::Unknown command code!\n");
break;
}
}
free(sysbusReq);
return Status;
}
int32_t SystemBus_FLJ_PeriodUpdate(SYSBUS *instPtr){
// TODO
return SUCCESS;
}
int32_t SystemBus_LJ_PeriodUpdate(SYSBUS *instPtr){
// TODO
return SUCCESS;
}
/*****************************************************************************/
/**
* @brief This function send a repose frame from system bus tx queue.
*
* @param instPtr A pointer to System Bus instance.
*
* @return None
*
******************************************************************************/
int32_t SystemBus_MakeResp(SYSBUS *instPtr){
ASSERT(instPtr != NULL);
int32_t Status;
SYSBUS_UART_FRAME *sysbusRsp;
if (CircQueuePop(instPtr->txQueue, (void**)(&sysbusRsp)) == false) {
DBG_WARNING("SystemBus::Nothing to be sent.\n");
return EIGNORE;
}
instPtr->isTxDone = false; // A transmission procedure is started.
Status = SysbusUart_Send(instPtr->uartInst, sysbusRsp);
free(sysbusRsp);
return Status;
}
/*****************************************************************************/
/**
* @brief This function handles the systembus tx irq events.
*
* @param instPtr A pointer to System Bus instance.
*
* @return None
*
******************************************************************************/
int32_t SystemBus_TxIntrHandler(SYSBUS *instPtr){
ASSERT(instPtr != NULL);
// nothing special...
instPtr->isTxDone = true; // A transmission procedure finished.
return SUCCESS;
}
/*****************************************************************************/
/**
* @brief This function handles the systembus rx irq events.
*
* @param instPtr A pointer to System Bus instance.
*
* @return None
*
******************************************************************************/
int32_t SystemBus_RxIntrHandler(SYSBUS *instPtr){
ASSERT(instPtr != NULL);
int32_t Status;
SYSBUS_UART_FRAME *sysbusReq;
instPtr->isRxDone = true; // whether reception successes or not, receiving procedure ended.
sysbusReq = malloc(sizeof(SYSBUS_UART_FRAME));
if (sysbusReq == NULL) {
return ENOMEM;
}
Status = SysbusUart_Recv(instPtr->uartInst, sysbusReq);
if(Status != SUCCESS) {
goto recv_error;
}
if (CircQueuePush(instPtr->rxQueue, (void *)sysbusReq) == false){
DBG_WARNING("SystemBus::RX Queue overflowed!\n");
Status = EQUEUE;
goto recv_error;
}
instPtr->isRxDone = false; // another reception is undergoing.
return SUCCESS;
recv_error:
free(sysbusReq);
return Status;
}
+65
View File
@@ -0,0 +1,65 @@
/*****************************************************************************/
/**
* Description: System bus protocol head file.
*
* Date: 2023-05-06 10:12
* Last Edit Time: [2023-05-06 10:13]
*
* Revisions: Rev 0.0
* History:
* [2023-05-06]: Initial version.
*
* Copyright(c) 2021 Beijing Institute of Technology.
*
******************************************************************************/
#ifndef __SYSTEMBUS_H_
#define __SYSTEMBUS_H_
/***************************** Include Files *********************************/
#include "systembus_uart.h" // SystemBus UART driver
#include "circ_queue.h"
#include <stdint.h>
#include <stdbool.h>
/************************** Constant Definitions *****************************/
/************************** Data Type Definitions ****************************/
// Definition of SystemBus instance.
typedef struct {
uintptr_t baseAddr;
uint32_t txQueueMax;
uint32_t rxQueueMax;
} SYSBUS_CONFIG;
typedef struct {
SYSBUS_CONFIG config;
SYSBUS_UART *uartInst;
CIRC_QUEUE *txQueue;
CIRC_QUEUE *rxQueue;
bool isRxDone;
bool isTxDone;
} SYSBUS;
/************************** Function Prototypes ******************************/
int32_t SystemBus_Init(SYSBUS **instPtr, SYSBUS_CONFIG *config);
int32_t SystemBus_HandleCmd(SYSBUS *instPtr);
int32_t SystemBus_FLJ_PeriodUpdate(SYSBUS *instPtr);
int32_t SystemBus_LJ_PeriodUpdate(SYSBUS *instPtr);
int32_t SystemBus_MakeResp(SYSBUS *instPtr);
int32_t SystemBus_TxIntrHandler(SYSBUS *instPtr);
int32_t SystemBus_RxIntrHandler(SYSBUS *instPtr);
bool SystemBus_IsReqPendding(SYSBUS *instPtr);
bool SystemBus_IsRsqPendding(SYSBUS *instPtr);
bool SystemBus_IsTxBusy(SYSBUS *instPtr);
bool SystemBus_IsRxBusy(SYSBUS *instPtr);
#endif //__SYSTEMBUS_H_
+228
View File
@@ -0,0 +1,228 @@
/*****************************************************************************/
/**
* Description: System bus uart driver implementation file.
*
* Date: 2023-05-06 10:59
* LastEditTime: 2023-05-06 21:56
* Revisions: Rev 0.0
* History:
* [2023-05-06]: Initial version.
*
* Copyright(c) 2022 Beijing Institute of Technology.
*
******************************************************************************/
/***************************** Include Files *******************************/
#include <stdlib.h>
#include <string.h>
#include <stdint.h>
#include <stdbool.h>
#include "systembus_uart.h"
#include "common.h"
// Control and status register
#define MODULE_VERSION 0
#define UART_STATUS 4
#define UART_SEND_CMD 8
#define UART_RECV_CNT 12
// Status code
#define UART_STATUS_TX_BUSY 0x00010000
#define UART_STATUS_RX_BUSY 0x01000000
// Data buffer register
#define UART_TXBUFF_LOW 1024
#define UART_TXBUFF_MAX 1024
#define UART_RXBUFF_LOW 2048
#define UART_RXBUFF_MAX 1024
// Frame Data offsets
#define FRAME_HEAD_LOW 0x5A
#define FRAME_HEAD_HIGH 0x54
#define FRAME_TAIL_LOW 0x5A
#define FRAME_TAIL_HIGH 0xFE
#define FRAME_HEAD_LEN 2
#define FRAME_TAIL_LEN 2
#define FRAME_DUMMY_LEN 1 // Dummy
#define FRAME_CHECK_LEN 1 // CheckSum
#define FRAME_INFO_LEN 3 // CheckSum, Dummy and DataLen
#define FRAME_OVERHEAD_LEN 7 // CheckSum, Dummy and DataLen
/*************************** Function Definitions ****************************/
/*****************************************************************************/
/**
* @brief Instance initial
*
* @param instPtr A pointer to frame uart instance structure.
* @param config Base address of frame uart, refer to "xparameters.h"
*
* @return None.
*
******************************************************************************/
int SysbusUart_Init(SYSBUS_UART **instPtr, SYSBUS_UART_CONFIG *config) {
ASSERT(instPtr != NULL);
ASSERT(config != NULL);
(*instPtr) = malloc(sizeof(SYSBUS_UART));
if ((*instPtr) == NULL){
return FAILURE;
}
(*instPtr)->config.baseAddr = config->baseAddr;
return SUCCESS;
}
/*****************************************************************************/
/**
* @brief Send a system bus frame.
*
* @param instPtr A pointer to SYSBUS_UART instance structure.
* @param buff A pointer to send data buffer
* @param dLen A integer indicate the send data buffer length in byte.
*
* @return
*
******************************************************************************/
int SysbusUart_Send(SYSBUS_UART* instPtr, SYSBUS_UART_FRAME *frame) {
ASSERT(instPtr != NULL);
ASSERT(frame != NULL);
uint8_t dLen, checkSum;
uint8_t sendLen;
uint8_t *sendBuff;
if (frame->len > UART_TXBUFF_MAX || frame->len == 0) {
return FAILURE;
}
sendBuff = malloc(sizeof(uint8_t) * UART_TXBUFF_MAX);
if (sendBuff == NULL) {
return FAILURE;
}
sendBuff[0] = FRAME_HEAD_LOW;
sendBuff[1] = FRAME_HEAD_HIGH;
dLen = 0;
checkSum = 0;
for (int i = 0; i < frame->len - 1; i++) {
if (frame->data[i] == FRAME_TAIL_LOW && frame->data[i+1] == FRAME_TAIL_HIGH) {
sendBuff[FRAME_HEAD_LEN + dLen] = 0x00;
dLen ++;
}
sendBuff[FRAME_HEAD_LEN + dLen] = frame->data[i];
checkSum += sendBuff[FRAME_HEAD_LEN + dLen];
dLen ++;
}
// Last Byte
sendBuff[FRAME_HEAD_LEN + dLen] = frame->data[frame->len - 1];
checkSum += sendBuff[FRAME_HEAD_LEN + dLen];
dLen ++;
// Dummy Byte
sendBuff[FRAME_HEAD_LEN + dLen] = 0x00;
// Check Sum
sendBuff[FRAME_HEAD_LEN + dLen + 1] = checkSum;
// Data Len
sendBuff[FRAME_HEAD_LEN + dLen + 2] = dLen;
// Frame Tail
sendBuff[FRAME_HEAD_LEN + dLen + 3] = FRAME_TAIL_LOW;
sendBuff[FRAME_HEAD_LEN + dLen + 4] = FRAME_TAIL_HIGH;
sendLen = dLen + FRAME_OVERHEAD_LEN;
if (sendLen > UART_TXBUFF_MAX) {
free(sendBuff);
return FAILURE;
}
memcpy((void *)(instPtr->config.baseAddr + UART_TXBUFF_LOW), sendBuff, (sendLen + sizeof(uint32_t) - 1)/sizeof(uint32_t) * sizeof(uint32_t));
free(sendBuff);
// Start Sending
SYSTEMBUS_UART_mWriteReg(instPtr->config.baseAddr, UART_SEND_CMD, sendLen);
return SUCCESS;
}
/*****************************************************************************/
/**
* @brief Get last system bus frame.
*
* @param instPtr A pointer to SYSBUS_UART instance structure.
* @param buff A pointer to receive data buffer.
*
* @return
*
******************************************************************************/
int SysbusUart_Recv(SYSBUS_UART* instPtr, SYSBUS_UART_FRAME *frame) {
ASSERT(instPtr != NULL);
ASSERT(frame != NULL);
uint8_t dLen, dWLen, plLen, checkSum, checkSumCal;
uint8_t *plBuff, *dBuff;
dLen = SYSTEMBUS_UART_mReadReg(instPtr->config.baseAddr, UART_RECV_CNT);
if (dLen == 0 || dLen > UART_TXBUFF_MAX) {
return EPARAM;
}
dWLen = (dLen + FRAME_HEAD_LEN + FRAME_INFO_LEN - 1)/4 + 1;
dBuff = malloc(sizeof(uint32_t)*dWLen);
if (dBuff == NULL){
return ENOMEM;
}
memcpy(dBuff, (void *)(instPtr->config.baseAddr + UART_RXBUFF_LOW), sizeof(uint32_t)*dWLen);
plBuff = dBuff + FRAME_HEAD_LEN;
checkSumCal = 0;
checkSum = plBuff[dLen + FRAME_DUMMY_LEN];
plLen = 0;
for(int i = 0; i < dLen; i++){
if (plBuff[i+1] == FRAME_TAIL_LOW && plBuff[i+2] == FRAME_TAIL_HIGH) {
continue;
}
checkSumCal += plBuff[i];
frame->data[plLen] = plBuff[i];
plLen++;
}
free(dBuff);
frame->len = plLen;
frame->checkSum = checkSumCal;
if (checkSumCal != checkSum){
frame->isValid = false;
return FAILURE;
}
frame->isValid = true;
return SUCCESS;
}
/*****************************************************************************/
/**
* @brief Get rx channel status.
*
* @param instPtr A pointer to SYSBUS_UART instance structure.
*
* @return true - SYSBUS_UART rx channel is busy.
* false - SYSBUS_UART rx channel is idle.
*
******************************************************************************/
bool SysbusUart_IsRxBusy(SYSBUS_UART* instPtr) {
ASSERT(instPtr != NULL);
uint32_t Status;
Status = SYSTEMBUS_UART_mReadReg(instPtr->config.baseAddr, UART_STATUS);
if (Status & UART_STATUS_RX_BUSY) {
return true;
}
else {
return false;
}
}
/*****************************************************************************/
/**
* @brief Get tx channel status.
*
* @param instPtr A pointer to SYSBUS_UART instance structure.
*
* @return true - SYSBUS_UART tx channel is busy.
* false - SYSBUS_UART tx channel is idle.
*
******************************************************************************/
bool SysbusUart_IsTxBusy(SYSBUS_UART* instPtr) {
ASSERT(instPtr != NULL);
uint32_t Status;
Status = SYSTEMBUS_UART_mReadReg(instPtr->config.baseAddr, UART_STATUS);
if (Status & UART_STATUS_TX_BUSY) {
return true;
}
else {
return false;
}
}
@@ -0,0 +1,96 @@
/*****************************************************************************/
/**
* Description: System bus uart driver implementation file.
*
* Date: 2023-05-06 10:59
* LastEditTime: 2023-05-06 21:48
* Revisions: Rev 0.0
* History:
* [2023-05-06]: Initial version.
*
* Copyright(c) 2022 Beijing Institute of Technology.
*
******************************************************************************/
#ifndef SYSTEMBUS_UART_H
#define SYSTEMBUS_UART_H
/****************** Include Files ********************/
#include <stdint.h>
#include <stdbool.h>
#include "util.h"
/**************************** Type Definitions *****************************/
/**
*
* Write a value to a SYSTEMBUS_UART register. A 32 bit write is performed.
* If the component is implemented in a smaller width, only the least
* significant data is written.
*
* @param baseAddr is the base address of the SYSTEMBUS_UARTdevice.
* @param offset is the register offset from the base to write to.
* @param data is the data written to the register.
*
* @return None.
*
* @note
* C-style signature:
* void SYSTEMBUS_UART_mWriteReg(uint32_t BaseAddress, unsigned RegOffset, uint32_t Data)
*
*/
#define SYSTEMBUS_UART_mWriteReg(baseAddr, offset, data) \
IO_Out32((baseAddr) + (offset), (uint32_t)(data))
/**
*
* Read a value from a SYSTEMBUS_UART register. A 32 bit read is performed.
* If the component is implemented in a smaller width, only the least
* significant data is read from the register. The most significant data
* will be read as 0.
*
* @param baseAddr is the base address of the SYSTEMBUS_UART device.
* @param offset is the register offset from the base to write to.
*
* @return Data is the data from the register.
*
* @note
* C-style signature:
* uint32_t SYSTEMBUS_UART_mReadReg(uint32_t BaseAddress, unsigned RegOffset)
*
*/
#define SYSTEMBUS_UART_mReadReg(baseAddr, offset) \
IO_In32((baseAddr) + (offset))
/************************** Data Type Definitions ****************************/
typedef struct {
uintptr_t baseAddr;
} SYSBUS_UART_CONFIG;
typedef struct {
SYSBUS_UART_CONFIG config;
} SYSBUS_UART;
typedef struct {
uint8_t len;
uint8_t checkSum;
uint8_t isValid;
uint8_t dummy;
uint8_t data[256];
} SYSBUS_UART_FRAME;
/************************** Function Prototypes ******************************/
// Instance initial
int SysbusUart_Init(SYSBUS_UART **instPtr, SYSBUS_UART_CONFIG *config);
// Send a system bus frame.
int SysbusUart_Send(SYSBUS_UART *instPtr, SYSBUS_UART_FRAME *frame);
// Get last system bus frame.
int SysbusUart_Recv(SYSBUS_UART *instPtr, SYSBUS_UART_FRAME *frame);
// Get system bus rx channel status.
bool SysbusUart_IsRxBusy(SYSBUS_UART *instPtr);
// Get system bus tx channel status.
bool SysbusUart_IsTxBusy(SYSBUS_UART *instPtr);
#endif // SYSTEMBUS_UART_H