#include // #include "uart.h" // #include "gpio.h" // #include "timer.h" #include "tl2cdr.h" 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_claim = (uint32_t*)( 0xc000000U + 0X200004 ); uint32_t flag_intTxEnd = 0; uint32_t flag_intRxError = 0; uint32_t flag_intRxStart = 0; uint32_t flag_intRxEnd = 0; void trap_entry(){ if( *plic_claim == 3 ){ flag_intTxEnd = 1; } else if( *plic_claim == 4 ){ flag_intRxError = 1; } else if( *plic_claim == 5 ){ flag_intRxStart = 1; } else if( *plic_claim == 6 ){ flag_intRxEnd = 1; } 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 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; *plic_enable_0_31 = 1 << 3 | 1 << 4 | 1 << 5 | 1 << 6; *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; i ++ ){ *cdr_txFifo = 0x00000000; } //等待发送完成标志 // 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); }