fix(systembus): correct systembus_psuart transceiver logic

* neglect radom power-up interrupts
* bound minimum and maximum transmit length
This commit is contained in:
Gatsby Van
2024-12-18 15:48:34 +08:00
parent 7f5a5bb72f
commit 384a51a198
3 changed files with 40 additions and 45 deletions
+5 -23
View File
@@ -20,6 +20,7 @@
#include <stdint.h>
#include <stdbool.h>
// Xilinx
#include "sleep.h"
#include "xscugic.h"
#include "drivers/platform/xilinx_irq.h"
#include "drivers/platform/xilinx_timer.h"
@@ -199,20 +200,6 @@ int32_t SetupInterruptSystem(struct irq_ctrl_desc *descPtr)
}
/* Initialize system bus interrupt. */
Status = irq_trigger_level_set(descPtr, SYSBUS_INTR_ID, IRQ_EDGE_RISING);
if (Status != SUCCESS)
{
DBG_ERROR("PHY_INTR trigger level set FAILED, ErrorCode: %" PRId32 ".\n", Status);
return Status;
}
// Set interrupt priority
Status = irq_set_priority(descPtr, SYSBUS_INTR_ID, 0x10);
if (Status != SUCCESS)
{
DBG_ERROR("PHY_INTR priority level set FAILED, ErrorCode: %" PRId32 ".\n", Status);
return Status;
}
// Connect the interrupt service routine isr1 to the interrupt controller
Status = irq_register_callback(descPtr, SYSBUS_INTR_ID, &sysbus_callback_desc);
if (Status != SUCCESS)
@@ -231,8 +218,8 @@ int32_t SetupInterruptSystem(struct irq_ctrl_desc *descPtr)
}
// Enable interrupts
irq_enable(descPtr, PHY_INTR_ID);
irq_enable(descPtr, PERIODIC_5MS_INTR_ID);
// irq_enable(descPtr, PHY_INTR_ID);
// irq_enable(descPtr, PERIODIC_5MS_INTR_ID);
irq_enable(descPtr, SYSBUS_INTR_ID);
irq_enable(descPtr, SCUTIMER_INTR_ID);
@@ -324,11 +311,6 @@ void ScuTimer_IntrHandler(void *context)
if(Status != SUCCESS) {
DBG_ERROR("Failed to generate remote check.\n");
}
// if (TimeCtrl_GetIntCnt(tmcInstPtr) - phyInstPtr->lastLogTime >= PHY_LOG_EXPIRE)
// {
// Phy_UpdateLogging(phyInstPtr);
// }
XScuTimer_ClearInterruptStatus((XScuTimer *)xdesc->instance);
}
else
@@ -436,6 +418,7 @@ int main(void)
DBG_PRINT("Physical started...\n");
Phy_Start(phyInstPtr);
// Linklayer_Start(linkInstPtr);
while (true)
@@ -451,8 +434,7 @@ int main(void)
}
if (SystemBus_IsRsqPending(sysbusDescPtr) && (!SystemBus_IsTxBusy(sysbusDescPtr)))
{
// FIXME: Required by 12 (CASC)
udelay(4000);
usleep(4000);
Status = SystemBus_MakeResp(sysbusDescPtr);
if (Status != SUCCESS)
{
+26 -14
View File
@@ -35,7 +35,7 @@
static void HwPSUart_IntrHandler(void *callBackRef, uint32_t event, uint32_t eventData) {
SYSBUS_PSUART *sysbusPSUartPtr = (SYSBUS_PSUART *) callBackRef;
/* All of the data has been sent */
if (event == XUARTPS_EVENT_SENT_DATA) {
if (event == XUARTPS_EVENT_SENT_DATA && sysbusPSUartPtr->currTxMsg != NULL) {
sysbusPSUartPtr->txCnt += eventData;
sysbusPSUartPtr->txDone = true;
free(sysbusPSUartPtr->currTxMsg);
@@ -43,31 +43,42 @@ static void HwPSUart_IntrHandler(void *callBackRef, uint32_t event, uint32_t eve
}
/* All of the data has been received */
if (event == XUARTPS_EVENT_RECV_DATA) {
if (event == XUARTPS_EVENT_RECV_DATA && sysbusPSUartPtr->currRxMsg != NULL) {
sysbusPSUartPtr->rxCnt += eventData;
sysbusPSUartPtr->rxDone = true;
if(sysbusPSUartPtr->rxCnt <= SYSBUS_MIN_TRANS_LEN) {
(void)SysbusPSUart_Recv(sysbusPSUartPtr, sysbusPSUartPtr->currRxMsg);
}
else {
sysbusPSUartPtr->currRxMsg->len = sysbusPSUartPtr->rxCnt - 2;
sysbusPSUartPtr->currRxMsg->isValid = crc16_check(sysbusPSUartPtr->currRxMsg->data,
sysbusPSUartPtr->currRxMsg->isValid = crc16_check(
(uint8_t*)sysbusPSUartPtr->currRxMsg->data,
sysbusPSUartPtr->currRxMsg->len,
sysbusPSUartPtr->currRxMsg->len,
sysbusPSUartPtr->config.crcPoly);
}
}
/* Receiving process reaches timeout */
if (event == XUARTPS_EVENT_RECV_TOUT) {
if (event == XUARTPS_EVENT_RECV_TOUT && sysbusPSUartPtr->currRxMsg != NULL) {
sysbusPSUartPtr->rxCnt += eventData;
sysbusPSUartPtr->rxDone = true;
if(sysbusPSUartPtr->rxCnt <= SYSBUS_MIN_TRANS_LEN) {
(void)SysbusPSUart_Recv(sysbusPSUartPtr, sysbusPSUartPtr->currRxMsg);
}
else {
sysbusPSUartPtr->currRxMsg->len = sysbusPSUartPtr->rxCnt - 2;
sysbusPSUartPtr->currRxMsg->isValid = crc16_check(sysbusPSUartPtr->currRxMsg->data,
sysbusPSUartPtr->currRxMsg->isValid = crc16_check(
(uint8_t*)sysbusPSUartPtr->currRxMsg->data,
sysbusPSUartPtr->currRxMsg->len,
sysbusPSUartPtr->currRxMsg->len,
sysbusPSUartPtr->config.crcPoly);
}
}
/* Data was received with an error */
if (event == XUARTPS_EVENT_RECV_ERROR) {
if (event == XUARTPS_EVENT_RECV_ERROR && sysbusPSUartPtr->currRxMsg != NULL) {
sysbusPSUartPtr->rxDone = true;
// Restart receiving
(void)SysbusPSUart_Recv(sysbusPSUartPtr, sysbusPSUartPtr->currRxMsg);
}
}
@@ -145,11 +156,12 @@ void SysbusPSUart_Destroy(SYSBUS_PSUART *instPtr) {
int SystemBus_PSUART_IntrHandler(SYSBUS_PSUART *instPtr) {
ASSERT(instPtr != NULL);
uint32_t irqState;
uint32_t irqState, irqMask;
irqMask = XUartPs_ReadReg(instPtr->hwInst.Config.BaseAddress, XUARTPS_IMR_OFFSET);
do {
XUartPs_InterruptHandler(&(instPtr->hwInst));
irqState = XUartPs_ReadReg(instPtr->hwInst.Config.BaseAddress, XUARTPS_IMR_OFFSET);
} while((irqState & XUARTPS_IXR_MASK) != 0x00000000);
irqState = irqMask & XUartPs_ReadReg(instPtr->hwInst.Config.BaseAddress, XUARTPS_ISR_OFFSET);
} while(irqState != 0x00);
return SUCCESS;
}
@@ -171,17 +183,17 @@ int SysbusPSUart_Send(SYSBUS_PSUART *instPtr, SYSBUS_PSUART_FRAME *frame) {
return FAILURE;
}
int Status;
if (frame->len + sizeof(uint16_t) > SYSBUS_MAX_TRANS_LEN || frame->len == 0) {
if (frame->len + sizeof(uint16_t) > SYSBUS_MAX_TRANS_LEN || frame->len < SYSBUS_MIN_TRANS_LEN) {
return FAILURE;
}
uint16_t crcVal;
size_t dlen = frame->len + sizeof(uint16_t);
Status = crc16_gen(frame->data, frame->len, instPtr->config.crcPoly, &crcVal);
Status = crc16_gen((uint8_t*)frame->data, frame->len, instPtr->config.crcPoly, &crcVal);
if(Status != SUCCESS) {
return FAILURE;
}
memcpy(frame->data + frame->len, &crcVal, sizeof(uint16_t));
XUartPs_Send(&(instPtr->hwInst), frame->data, dlen);
XUartPs_Send(&(instPtr->hwInst), (uint8_t*)frame->data, dlen);
instPtr->currTxMsg = frame;
instPtr->txDone = false;
return SUCCESS;
@@ -204,7 +216,7 @@ int SysbusPSUart_Recv(SYSBUS_PSUART *instPtr, SYSBUS_PSUART_FRAME *frame)
if (SysbusPSUart_IsRxBusy(instPtr) == true){
return FAILURE;
}
instPtr->rxCnt = XUartPs_Recv(&(instPtr->hwInst), frame->data, frame->len);
instPtr->rxCnt = XUartPs_Recv(&(instPtr->hwInst), (uint8_t*)frame->data, sizeof(frame->data));
instPtr->currRxMsg = frame;
instPtr->rxDone = false;
return SUCCESS;
+1
View File
@@ -45,6 +45,7 @@
#define SYSBUS_PSUART_1_STOP_BIT XUARTPS_FORMAT_1_STOP_BIT /**< 1 stop bit */
#define SYSBUS_MAX_TRANS_LEN 1024
#define SYSBUS_MIN_TRANS_LEN 4
/**
* @struct SYSBUS_UART_FRAME