#include // #include "uart.h" // #include "gpio.h" // #include "timer.h" #include "tl2cdr.h" volatile uint32_t *plic_priority_3 = (uint32_t*)( 0xc000000U + 0X000004 * 3); volatile uint32_t *plic_priority_4 = (uint32_t*)( 0xc000000U + 0X000004 * 4); volatile uint32_t *plic_priority_5 = (uint32_t*)( 0xc000000U + 0X000004 * 5); volatile uint32_t *plic_priority_6 = (uint32_t*)( 0xc000000U + 0X000004 * 6); volatile uint32_t *plic_priority_TxEnd = (uint32_t*)( 0xc000000U + 0X000004 * CDR_INT_TXEND); volatile uint32_t *plic_priority_RxError = (uint32_t*)( 0xc000000U + 0X000004 * CDR_INT_RXERROR); volatile uint32_t *plic_priority_RxStart = (uint32_t*)( 0xc000000U + 0X000004 * CDR_INT_RXSTART); volatile uint32_t *plic_priority_RxEnd = (uint32_t*)( 0xc000000U + 0X000004 * CDR_INT_RXEND); volatile uint32_t *plic_priority_18 = (uint32_t*)( 0xc000000U + 0X000004 * 18); volatile uint32_t *plic_priority_19 = (uint32_t*)( 0xc000000U + 0X000004 * 19); volatile uint32_t *plic_priority_20 = (uint32_t*)( 0xc000000U + 0X000004 * 20); volatile uint32_t *plic_priority_21 = (uint32_t*)( 0xc000000U + 0X000004 * 21); volatile uint32_t *plic_pending_0_31 = (uint32_t*)( 0xc000000U + 0X001000 ); volatile uint32_t *plic_enable_0_31 = (uint32_t*)( 0xc000000U + 0X002000 ); volatile uint32_t *plic_threshold_0 = (uint32_t*)( 0xc000000U + 0X200000 ); volatile uint32_t *plic_claim = (uint32_t*)( 0xc000000U + 0X200004 ); volatile uint32_t flag_intTxEnd = 0; volatile uint32_t flag_intRxError = 0; volatile uint32_t flag_intRxStart = 0; volatile uint32_t flag_intRxEnd = 0; void plic_handle(){ // 从 PLIC 中获取中断源 ID uint32_t claim = *plic_claim; if( claim == CDR_INT_TXEND ){ flag_intTxEnd = 1; } else if( claim == CDR_INT_RXERROR ){ flag_intRxError = 1; } else if( claim == CDR_INT_RXSTART ){ flag_intRxStart = 1; } else if( claim == CDR_INT_RXEND ){ flag_intRxEnd = 1; } // 通知 PLIC 完成中断处理 *plic_claim = claim; return; } static inline void error() { while(1); } // extern volatile uint32_t *cdr_status = (uint32_t*)( TL2CDR_BASE + CDR_ReadStatus ); //read // extern volatile uint32_t *cdr_txLen = (uint32_t*)( TL2CDR_BASE + CDR_WriteTxLen ); //write // extern volatile uint32_t *cdr_txFifo = (uint32_t*)( TL2CDR_BASE + CDR_WriteTxFifo ); //write // extern volatile uint32_t *cdr_direct = (uint32_t*)( TL2CDR_BASE + CDR_WriteTransDir ); //write // extern volatile uint32_t *cdr_softReset = (uint32_t*)( TL2CDR_BASE + CDR_WriteSoftReset ); //write // extern volatile uint32_t *cdr_rxLen = (uint32_t*)( TL2CDR_BASE + CDR_ReadRxLen ); //read // extern volatile uint32_t *cdr_rxFifo = (uint32_t*)( TL2CDR_BASE + CDR_ReadRxFifo ); //read //extern const uint8_t mst_svr_code[]; //uint32_t (*init_svr_code)(void); void main() { uint32_t readDat; uint32_t operator; uint32_t downRecvLen; uint32_t upRecvLen; uint32_t slvNum; uint32_t totNum; uint32_t isLast; uint32_t led = 0; uint32_t crc; //init_svr_code = (uint32_t (*)(void))mst_svr_code; *plic_enable_0_31 = 1 << CDR_INT_TXEND | 1 << CDR_INT_RXERROR | 1 << CDR_INT_RXSTART | 1 << CDR_INT_RXEND; *plic_priority_TxEnd = 1; *plic_priority_RxError = 1; *plic_priority_RxStart = 1; *plic_priority_RxEnd = 1; *plic_threshold_0 = 0; {//再写一次实现延迟,等从机的复位完成 *plic_enable_0_31 = 1 << CDR_INT_TXEND | 1 << CDR_INT_RXERROR | 1 << CDR_INT_RXSTART | 1 << CDR_INT_RXEND; *plic_priority_TxEnd = 1; *plic_priority_RxError = 1; *plic_priority_RxStart = 1; *plic_priority_RxEnd = 1; *plic_threshold_0 = 0; } //while (init_svr_code() != 1); *cdr_softReset = 1; //复位脉冲 *cdr_direct = 0; register uint32_t flag; // asm volatile ( //timer 2s // "1:\n" // "rdcycle %0\n" // // "srli %0, %0, 12\n" // "srli %0, %0, 27\n" // // "srli %0, %0, 26\n" // "andi %0, %0, 0x1\n" // "beqz %0, 1b\n" // :"+r"(flag) // ); // if( led ){ // *WriteGpio = 0xFFFFFFFF; // led = 0; // } else{ // *WriteGpio = 0x0; // led = 1; // } //发送下行包头 *cdr_txLen = 520; //总长520 *cdr_txFifo = (512 << 20) |( 0 << 16) | 0x0000; //负载长度512,操作数0, 参数全0 *cdr_txFifo = 0x00000000; for( uint32_t i = 0; i < 512/4 - 1; i ++ ){ *cdr_txFifo = 0x00000000; } crc = *cdr_txCrc; *cdr_txFifo = crc; //等待发送完成标志 // asm volatile ( // "1:\n" // "andi %0, sp, 0x01\n" // "beqz %0, 1b\n" // "andi sp, sp, 0xFE\n" // :"+r"(flag) // ); while( !flag_intTxEnd ); flag_intTxEnd = 0; *cdr_softReset = 1; //复位脉冲 *cdr_direct = 1; //方向切换上行 //接收第一个包 // asm volatile ( // "1:\n" // "andi %0, sp, 0x04\n" // "beqz %0, 1b\n" // "andi sp, sp, 0xFB\n" // :"+r"(flag) // ); while(!flag_intRxStart); flag_intRxStart = 0; readDat = *cdr_rxFifo; // operator = (readDat >> 16) & 0xf; //速度不够,不校验 upRecvLen = readDat >> 20; //接收第二个包 // asm volatile ( // "andi %0, sp, 0x08\n" // "1:\n" // "bnez %0, 1b\n" //error //速度不够,不校验 // :"+r"(flag), // ); if( flag_intRxError ){ while(1); } uint32_t temp = *cdr_rxFifo; //上行转发负载 for( uint32_t i = 0; i < (upRecvLen >> 2); i ++ ){ //一次传4byte if( flag_intRxError ){ while(1); } // register uint32_t upData; // asm volatile ( // "andi %0, sp, 0x80\n" // "1:\n" // "bnez %0, 1b\n" //error 速度不够,不再检查接收 // "lw %1, 0x01c(x0)\n" // :"+r"(flag), "+r"(upData) // ); } //CRC if( flag_intRxError ){ while(1); } // asm volatile ( // "andi %0, sp, 0x08\n" // "1:\n" // "bnez %0, 1b\n" //error // :"+r"(flag) // ); //uint32_t crc = *cdr_rxFifo; //CRC //等待接收完成标志 // asm volatile ( // "1:\n" // "andi %0, sp, 0x08\n" // "beqz %0, 1b\n" // "andi sp, sp, 0xF7\n" // :"+r"(flag) // ); while(!flag_intRxEnd); flag_intRxEnd = 0; totNum = (upRecvLen >> 3); }