#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); } void main() { register uint32_t readDat; register uint32_t operator; register uint32_t downRecvLen; register uint32_t upRecvLen; register uint32_t crc; uint8_t localData[512]; uint32_t slvNum; uint32_t totNum; register uint32_t isLast; register uint32_t flag; *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(1){ *cdr_softReset = 1; //复位脉冲 *cdr_direct = 0; isLast = *cdr_IsLast; // asm volatile( // "sw x0, 0x10(x0)\n" //cdr_softReset 写入任意值进行复位//复位脉冲 // "lw %0, 0x408(x0)\n" //ReadIsLast 获取是否为最后一个从机 // "sw x0, 0xc(x0)\n" //设置CDR方向 // : "+r"(isLast) // ); // *WriteGpio = 0x01; //等待接收开始中断 while(!flag_intRxStart); // asm volatile ( // "1:\n" // "andi %0, sp, 0x04\n" // "beqz %0, 1b\n" // "andi sp, sp, 0xFB\n" // : "+r"(flag) // ); readDat = *cdr_rxFifo; operator = (readDat >> 16) & 0xf; downRecvLen = readDat >> 20; readDat = *cdr_rxFifo; // asm volatile ( // "lw %0, 0x1c(x0)\n" //read rxfifo // "srli %1, %0, 16\n" // operator = readDat >> 16 // "srli %2, %1, 4\n" // downRecvLen = operator >> 4 // "andi %1, %1,0xf\n" // operator = operator & 0xf // "lw %0, 0x1c(x0)\n" //read rxfifo // : "+r"(readDat), "+r"(operator), "+r"(downRecvLen) // ); // *WriteGpio = 0x03; if( operator == 0 ){ //接收本地包 for( uint32_t i = 0; i < 2; i++ ) { if( flag_intRxError ){ while(1); } *(localData+i) = *cdr_rxFifo; // asm volatile ( // "andi %0, sp, 0x08\n" // "1:\n" // "bnez %0, 1b\n" //error // "lw %1, 0x1c(x0)\n" //read rxfifo // : "+r"(flag), "+r"(readDat) // ); } // *WriteGpio = 0x07; register uint32_t downSendLen; downSendLen = downRecvLen - 8; if(!isLast){ // 下行转发新建包头 register uint32_t downSendHead; *cdr_txLen = downRecvLen; downSendHead = (downSendLen << 20) | ( 0 << 16) | 0; *cdr_txFifo = downSendHead; *cdr_txFifo = 0; // asm volatile ( // "sw %0, 0x4(x0)\n" // *cdr_txLen = downRecvLen // "addi %2, %0, -8\n" //downSendLen = downRecvLen - 8; // "slli %1, %2, 20\n" // downSendHead = (downSendLen << 20) |( 0 << 16) | 0; // "sw %1, 0x8(x0)\n" //*cdr_txFifo = downSendHead // "sw x0, 0x8(x0)\n" //*cdr_txFifo = 0 // : "+r"(downRecvLen), "+r"(downSendHead), "+r"(downSendLen) // ); //下行转发负载 for( uint32_t i = 0; i < (downSendLen); i+=4 ){ //一次传4byte register uint32_t forData; if( flag_intRxError){ while(1); } *cdr_txFifo = *cdr_rxFifo; // asm volatile ( // "andi %0, sp, 0x08\n" // "1:\n" // "bnez %0, 1b\n" //error 速度不够,不再检查接收 // "lw %1, 0x01c(x0)\n" // "sw %1, 0x008(x0)\n" // : // "+r"(flag), "+r"(forData) // ); } } else{ //isLast //空转掉剩余负载 for( uint32_t i = 0; i < (downSendLen >> 2); i++ ){ //一次传4byte register uint32_t forData; if( flag_intRxError ){ while(1); } readDat = *cdr_rxFifo; // asm volatile ( // "andi %0, sp, 0x08\n" // "1:\n" // "bnez %0, 1b\n" //error 速度不够,不再检查接收 // "lw %1, 0x01c(x0)\n" // : "+r"(flag), "+r"(forData) // ); } } // *WriteGpio = 0x0f; //CRC if( flag_intRxError ){ while(1); } crc = *cdr_rxFifo; // asm volatile ( // "andi %0, sp, 0x08\n" // "1:\n" // "bnez %0, 1b\n" //error // "lw %1, 0x1c(x0)\n" //read rxfifo // : "+r"(flag), "+r"(readDat) // ); // *WriteGpio = 0x1f; //等待接收完成标志 while(!flag_intRxEnd); flag_intRxEnd = 0; // asm volatile ( // "1:\n" // "andi %0, sp, 0x08\n" // "beqz %0, 1b\n" // "andi sp, sp, 0xF7\n" // : "+r"(flag) // ); // *WriteGpio = 0x3f; if(!isLast){ //等待发送完成标志 while(!flag_intTxEnd); flag_intTxEnd = 0; // asm volatile ( // "1:\n" // "andi %0, sp, 0x01\n" // "beqz %0, 1b\n" // "andi sp, sp, 0xFE\n" // :"+r"(flag) // ); } // *WriteGpio = 0x7f; register uint32_t one = 1; register uint32_t txLen; register uint32_t txHeader; *cdr_softReset = 1; *cdr_direct = 1; // asm volatile( // "sw x0, 0x10(x0)\n" //cdr_softReset 写入任意值进行复位//复位脉冲 // "sw %0, 0xc(x0)\n" //设置CDR方向 // : "+r"(one) // ); if(!isLast){ //上行转发 //接收第一个包 while(!flag_intRxStart); flag_intRxStart = 0; // asm volatile ( // "1:\n" // "andi %0, sp, 0x04\n" // "beqz %0, 1b\n" // "andi sp, sp, 0xFB\n" // :"+r"(flag) // ); //接收第一个包 if(flag_intRxError){while(1);} readDat = *cdr_rxFifo; upRecvLen = readDat >> 20; txLen = upRecvLen + 16; txHeader = upRecvLen + 8; txHeader = (txHeader << 20) | ( 0 << 16) | 0; //发送上行包头 *cdr_txLen = txLen; *cdr_txFifo = txHeader; *cdr_txFifo = 0; // asm volatile ( // "lw %0, 0x1c(x0)\n" //read rxfifo // "srli %1, %0, 20\n" // upRecvLen = readDat >> 20 // "addi %2, %1, 16\n" //txLen = upRecvLen + 16 // "addi %3, %1, 8\n" //txHeader = upRecvLen + 8 // "slli %3, %3, 20\n" //txHeader = txHeader << 20 |( 0 << 16) | 0 // "sw %2, 0x4(x0)\n" //*cdr_txLen = txLen // "sw %3, 0x8(x0)\n" //*cdr_txFifo = txHeader // "sw x0, 0x8(x0)\n" //*cdr_txFifo = 0 // : "+r"(readDat), "+r"(upRecvLen), "+r"( txLen ), "+r"( txHeader ) // ); for( uint32_t i = 0; i < 8/4; i ++ ){ *cdr_txFifo = 0; // asm volatile ( // "sw x0, 0x8(x0)\n" //*cdr_txFifo = 0; // ); } //接收第二个包 if(flag_intRxError){while(1);} readDat = *cdr_rxFifo; // asm volatile ( // "andi %0, sp, 0x08\n" // "1:\n" // "bnez %0, 1b\n" //error //速度不够,不校验 // "lw %1, 0x1c(x0)\n" //read rxfifo // :"+r"(flag), "+r"(readDat) // ); //上行转发负载 for( uint32_t i = 0; i < (upRecvLen); i += 4 ){ //一次传4byte register uint32_t forData; if( flag_intRxError ){ while(1); } *cdr_txFifo = *cdr_rxFifo; // asm volatile ( // "andi %0, sp, 0x80\n" // "1:\n" // "bnez %0, 1b\n" //error 速度不够,不再检查接收 // "lw %1, 0x01c(x0)\n" // "sw %1, 0x008(x0)\n" // :"+r"(flag), "+r"(forData) // ); } //CRC if( flag_intRxError ){ while(1); } crc = *cdr_rxFifo; // asm volatile ( // "andi %0, sp, 0x08\n" // "1:\n" // "bnez %0, 1b\n" //error // "lw %0, 0x1c(x0)\n" //read rxfifo // :"+r"(flag), "+r"(readDat) // ); //等待接收完成标志 while(!flag_intRxEnd); flag_intRxEnd = 0; // asm volatile ( // "1:\n" // "andi %0, sp, 0x08\n" // "beqz %0, 1b\n" // "andi sp, sp, 0xF7\n" // :"+r"(flag) // ); totNum = slvNum + (upRecvLen >> 3) - 1; } else { //islast //发送上行包头 txLen = upRecvLen + 16; txHeader = ( 8 << 20 ) | ( 0 << 16) | 0; *cdr_txLen = txLen; *cdr_txFifo = txHeader; *cdr_txFifo = 0; // asm volatile ( // "li %0, 16\n" //txLen = upRecvLen + 16 // "sw %0, 0x4(x0)\n" //*cdr_txLen = txLen // "lui %1, 0x800\n" //txHeader = 8 << 20 |( 0 << 16) | 0 // "sw %1, 0x8(x0)\n" //*cdr_txFifo = txHeader // "sw x0, 0x8(x0)\n" //*cdr_txFifo = 0 // : "+r"( txLen ), "+r"( txHeader ) // ); for( uint32_t i = 0; i < 8/4; i ++ ){ *cdr_txFifo = 0; // asm volatile ( // "sw x0, 0x8(x0)\n" //*cdr_txFifo = 0; // ); } } //等待发送完成标志 while(!flag_intTxEnd); flag_intTxEnd = 0; // asm volatile ( // "1:\n" // "andi %0, sp, 0x01\n" // "beqz %0, 1b\n" // "andi sp, sp, 0xFE\n" // :"+r"(flag) // ); slvNum = 64 - ( downRecvLen >> 3 ); // *WriteGpio = 1 << slvNum; } else if ( operator == 1 ){ // error(); } else if ( operator == 2 ){ // error(); } else { // error(); } } }