#include // #include "uart.h" // #include "gpio.h" // #include "timer.h" #include "custom_ops.S" volatile uint32_t *cdr_status = (uint32_t*)( 0x000 + 0x0 ); //read volatile uint32_t *cdr_txLen = (uint32_t*)( 0x000 + 0x4 ); //write volatile uint32_t *cdr_txFifo = (uint32_t*)( 0x000 + 0x8 ); //write volatile uint32_t *cdr_direct = (uint32_t*)( 0x000 + 0xc ); //write volatile uint32_t *cdr_softReset = (uint32_t*)( 0x000 + 0x10 ); //write volatile uint32_t *cdr_rxLen = (uint32_t*)( 0x000 + 0x18 ); //read volatile uint32_t *cdr_rxFifo = (uint32_t*)( 0x000 + 0x1c ); //read volatile uint32_t *WriteGpio = (uint32_t*) ( 0x400); volatile uint32_t *ReadGpio = (uint32_t*) ( 0x400); volatile uint32_t *ReadIsLast = (uint32_t*) ( 0x408); // static inline void error() { // while(1); // } void main() { register uint32_t readDat; register uint32_t operator; register uint32_t downRecvLen; register uint32_t upRecvLen; uint32_t slvNum; uint32_t totNum; register uint32_t isLast; register uint32_t flag; asm volatile ( "li sp, 0\n" ".4byte 0x600600b\n" ); while(1){ 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; //等待接收开始中断 asm volatile ( "1:\n" "andi %0, sp, 0x04\n" "beqz %0, 1b\n" "andi sp, sp, 0xFB\n" : "+r"(flag) ); 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++ ) { 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; if(!isLast){ // 下行转发新建包头 register uint32_t downSendHead; 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; 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; 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 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; //等待接收完成标志 asm volatile ( "1:\n" "andi %0, sp, 0x08\n" "beqz %0, 1b\n" "andi sp, sp, 0xF7\n" : "+r"(flag) ); // *WriteGpio = 0x3f; if(!isLast){ //等待发送完成标志 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; asm volatile( "sw x0, 0x10(x0)\n" //cdr_softReset 写入任意值进行复位//复位脉冲 "sw %0, 0xc(x0)\n" //设置CDR方向 : "+r"(one) ); if(!isLast){ //上行转发 //接收第一个包 asm volatile ( "1:\n" "andi %0, sp, 0x04\n" "beqz %0, 1b\n" "andi sp, sp, 0xFB\n" :"+r"(flag) ); //发送上行包头 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 ++ ){ asm volatile ( "sw x0, 0x8(x0)\n" //*cdr_txFifo = 0; ); } //接收第二个包 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; 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 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) ); //等待接收完成标志 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 //发送上行包头 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 ++ ){ asm volatile ( "sw x0, 0x8(x0)\n" //*cdr_txFifo = 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(); } } }