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 <stdint.h>
#include <stdbool.h> #include <stdbool.h>
// Xilinx // Xilinx
#include "sleep.h"
#include "xscugic.h" #include "xscugic.h"
#include "drivers/platform/xilinx_irq.h" #include "drivers/platform/xilinx_irq.h"
#include "drivers/platform/xilinx_timer.h" #include "drivers/platform/xilinx_timer.h"
@@ -199,20 +200,6 @@ int32_t SetupInterruptSystem(struct irq_ctrl_desc *descPtr)
} }
/* Initialize system bus interrupt. */ /* 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 // Connect the interrupt service routine isr1 to the interrupt controller
Status = irq_register_callback(descPtr, SYSBUS_INTR_ID, &sysbus_callback_desc); Status = irq_register_callback(descPtr, SYSBUS_INTR_ID, &sysbus_callback_desc);
if (Status != SUCCESS) if (Status != SUCCESS)
@@ -231,8 +218,8 @@ int32_t SetupInterruptSystem(struct irq_ctrl_desc *descPtr)
} }
// Enable interrupts // Enable interrupts
irq_enable(descPtr, PHY_INTR_ID); // irq_enable(descPtr, PHY_INTR_ID);
irq_enable(descPtr, PERIODIC_5MS_INTR_ID); // irq_enable(descPtr, PERIODIC_5MS_INTR_ID);
irq_enable(descPtr, SYSBUS_INTR_ID); irq_enable(descPtr, SYSBUS_INTR_ID);
irq_enable(descPtr, SCUTIMER_INTR_ID); irq_enable(descPtr, SCUTIMER_INTR_ID);
@@ -324,11 +311,6 @@ void ScuTimer_IntrHandler(void *context)
if(Status != SUCCESS) { if(Status != SUCCESS) {
DBG_ERROR("Failed to generate remote check.\n"); 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); XScuTimer_ClearInterruptStatus((XScuTimer *)xdesc->instance);
} }
else else
@@ -435,6 +417,7 @@ int main(void)
DBG_PRINT("Physical started...\n"); DBG_PRINT("Physical started...\n");
Phy_Start(phyInstPtr); Phy_Start(phyInstPtr);
// Linklayer_Start(linkInstPtr); // Linklayer_Start(linkInstPtr);
@@ -451,8 +434,7 @@ int main(void)
} }
if (SystemBus_IsRsqPending(sysbusDescPtr) && (!SystemBus_IsTxBusy(sysbusDescPtr))) if (SystemBus_IsRsqPending(sysbusDescPtr) && (!SystemBus_IsTxBusy(sysbusDescPtr)))
{ {
// FIXME: Required by 12 (CASC) usleep(4000);
udelay(4000);
Status = SystemBus_MakeResp(sysbusDescPtr); Status = SystemBus_MakeResp(sysbusDescPtr);
if (Status != SUCCESS) if (Status != SUCCESS)
{ {
+34 -22
View File
@@ -35,7 +35,7 @@
static void HwPSUart_IntrHandler(void *callBackRef, uint32_t event, uint32_t eventData) { static void HwPSUart_IntrHandler(void *callBackRef, uint32_t event, uint32_t eventData) {
SYSBUS_PSUART *sysbusPSUartPtr = (SYSBUS_PSUART *) callBackRef; SYSBUS_PSUART *sysbusPSUartPtr = (SYSBUS_PSUART *) callBackRef;
/* All of the data has been sent */ /* 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->txCnt += eventData;
sysbusPSUartPtr->txDone = true; sysbusPSUartPtr->txDone = true;
free(sysbusPSUartPtr->currTxMsg); 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 */ /* 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->rxCnt += eventData;
sysbusPSUartPtr->rxDone = true; sysbusPSUartPtr->rxDone = true;
sysbusPSUartPtr->currRxMsg->len = sysbusPSUartPtr->rxCnt - 2; if(sysbusPSUartPtr->rxCnt <= SYSBUS_MIN_TRANS_LEN) {
sysbusPSUartPtr->currRxMsg->isValid = crc16_check(sysbusPSUartPtr->currRxMsg->data, (void)SysbusPSUart_Recv(sysbusPSUartPtr, sysbusPSUartPtr->currRxMsg);
sysbusPSUartPtr->currRxMsg->len, }
sysbusPSUartPtr->currRxMsg->len, else {
sysbusPSUartPtr->config.crcPoly); sysbusPSUartPtr->currRxMsg->len = sysbusPSUartPtr->rxCnt - 2;
sysbusPSUartPtr->currRxMsg->isValid = crc16_check(
(uint8_t*)sysbusPSUartPtr->currRxMsg->data,
sysbusPSUartPtr->currRxMsg->len,
sysbusPSUartPtr->currRxMsg->len,
sysbusPSUartPtr->config.crcPoly);
}
} }
/* Receiving process reaches timeout */ /* Receiving process reaches timeout */
if (event == XUARTPS_EVENT_RECV_TOUT) { if (event == XUARTPS_EVENT_RECV_TOUT && sysbusPSUartPtr->currRxMsg != NULL) {
sysbusPSUartPtr->rxCnt += eventData; sysbusPSUartPtr->rxCnt += eventData;
sysbusPSUartPtr->rxDone = true; sysbusPSUartPtr->rxDone = true;
sysbusPSUartPtr->currRxMsg->len = sysbusPSUartPtr->rxCnt - 2; if(sysbusPSUartPtr->rxCnt <= SYSBUS_MIN_TRANS_LEN) {
sysbusPSUartPtr->currRxMsg->isValid = crc16_check(sysbusPSUartPtr->currRxMsg->data, (void)SysbusPSUart_Recv(sysbusPSUartPtr, sysbusPSUartPtr->currRxMsg);
sysbusPSUartPtr->currRxMsg->len, }
sysbusPSUartPtr->currRxMsg->len, else {
sysbusPSUartPtr->config.crcPoly); sysbusPSUartPtr->currRxMsg->len = sysbusPSUartPtr->rxCnt - 2;
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 */ /* Data was received with an error */
if (event == XUARTPS_EVENT_RECV_ERROR) { if (event == XUARTPS_EVENT_RECV_ERROR && sysbusPSUartPtr->currRxMsg != NULL) {
sysbusPSUartPtr->rxDone = true; sysbusPSUartPtr->rxDone = true;
// Restart receiving
(void)SysbusPSUart_Recv(sysbusPSUartPtr, sysbusPSUartPtr->currRxMsg); (void)SysbusPSUart_Recv(sysbusPSUartPtr, sysbusPSUartPtr->currRxMsg);
} }
} }
@@ -145,11 +156,12 @@ void SysbusPSUart_Destroy(SYSBUS_PSUART *instPtr) {
int SystemBus_PSUART_IntrHandler(SYSBUS_PSUART *instPtr) { int SystemBus_PSUART_IntrHandler(SYSBUS_PSUART *instPtr) {
ASSERT(instPtr != NULL); ASSERT(instPtr != NULL);
uint32_t irqState; uint32_t irqState, irqMask;
irqMask = XUartPs_ReadReg(instPtr->hwInst.Config.BaseAddress, XUARTPS_IMR_OFFSET);
do { do {
XUartPs_InterruptHandler(&(instPtr->hwInst)); XUartPs_InterruptHandler(&(instPtr->hwInst));
irqState = XUartPs_ReadReg(instPtr->hwInst.Config.BaseAddress, XUARTPS_IMR_OFFSET); irqState = irqMask & XUartPs_ReadReg(instPtr->hwInst.Config.BaseAddress, XUARTPS_ISR_OFFSET);
} while((irqState & XUARTPS_IXR_MASK) != 0x00000000); } while(irqState != 0x00);
return SUCCESS; return SUCCESS;
} }
@@ -171,17 +183,17 @@ int SysbusPSUart_Send(SYSBUS_PSUART *instPtr, SYSBUS_PSUART_FRAME *frame) {
return FAILURE; return FAILURE;
} }
int Status; 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; return FAILURE;
} }
uint16_t crcVal; uint16_t crcVal;
size_t dlen = frame->len + sizeof(uint16_t); 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) { if(Status != SUCCESS) {
return FAILURE; return FAILURE;
} }
memcpy(frame->data + frame->len, &crcVal, sizeof(uint16_t)); 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->currTxMsg = frame;
instPtr->txDone = false; instPtr->txDone = false;
return SUCCESS; return SUCCESS;
@@ -204,7 +216,7 @@ int SysbusPSUart_Recv(SYSBUS_PSUART *instPtr, SYSBUS_PSUART_FRAME *frame)
if (SysbusPSUart_IsRxBusy(instPtr) == true){ if (SysbusPSUart_IsRxBusy(instPtr) == true){
return FAILURE; 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->currRxMsg = frame;
instPtr->rxDone = false; instPtr->rxDone = false;
return SUCCESS; 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_PSUART_1_STOP_BIT XUARTPS_FORMAT_1_STOP_BIT /**< 1 stop bit */
#define SYSBUS_MAX_TRANS_LEN 1024 #define SYSBUS_MAX_TRANS_LEN 1024
#define SYSBUS_MIN_TRANS_LEN 4
/** /**
* @struct SYSBUS_UART_FRAME * @struct SYSBUS_UART_FRAME