Part Number: BEAGLEBK
Tool/software: TI C/C++ Compiler
Hello!
I have a question about MII_RT (mii0) interface at the BeagleBone Black. I use the PRU Cape Demo Software (https://git.ti.com/pru-software-support-package/pru-software-support-package/trees/master/pru_cape) example. I change the LED1 example for MII_RT using.
Tx work good (I connect LAN8710 ethernet phy (Microchip) to the BeagleBone and can see packets which I send on the WireShark on the PC), I have the problems with Rx. For testing Rx mode I use the LAN8710 configuring at NEAR-END LOOPBACK mode. I set the MII_Rx mode without Rx_L2 (because of https://e2e.ti.com/support/development_tools/compiler/f/343/t/586407?tisearch=e2e-sitesearch&keymatch=am335x%20pru%20mii last answer advice).
My program for the PRU:
volatile register uint32_t __R30; volatile register uint32_t __R31; void main(void) { volatile uint32_t rx_data; /* Clear SYSCFG[STANDBY_INIT] to enable OCP master port */ CT_CFG.SYSCFG_bit.STANDBY_INIT = 0; /* TODO: Create stop condition, else it will toggle indefinitely */ while (1) { /* MII */ __R31 = (1<<18);//rx_reset (I try do not reset the RX, not any difference), look spruh73p, table 4_36 __delay_cycles(400000); int i; for (i=0; i<50; i++)//send the pack start { __R30 = 0xFFFF0000|0x7755;// 0x7755 - data __R31 = (1<<25);//push to the mii tx } __R30 = 0xFFFF0001; ;// 0x1 - data __R31 = (1<<25)|(1<<29);//push to the mii tx, EOF_TX, send the pack finish CT_SHAREDMEM.mem[0] = i; check that the share memory work good, I must read correct value “I” from the AM3358 main programm __delay_cycles(40000); rx_data = __R31;//read the data and status at the MII_RX_L1 CT_SHAREDMEM.mem[1] = rx_data;//I need to read rx_data at the AM3358 main programm __delay_cycles(400); __R31 = (1<<17);//rx_pop16 __delay_cycles(400); rx_data = __R31; __delay_cycles(40000); CT_SHAREDMEM.mem[2] = rx_data; __delay_cycles(400); CT_SHAREDMEM.mem[4] = 0x55;
My program for the AM3358:
//sets pin mux for PRU cape PRUCapePinmux(); //Sets and Enables clock, Zeros memory, resets PRU PRUICSSInit(); //****************************************************************************** // MII //****************************************************************************** gpi_cfg = HWREG(SOC_PRUICSS1_REGS + SOC_PRUICSS_CFG_OFFSET + 0x8); HWREG(SOC_PRUICSS1_REGS + SOC_PRUICSS_CFG_OFFSET + 0x8) = gpi_cfg | 0x3;// GPI to MII mode HWREG(SOC_PRUICSS1_REGS + SOC_PRUICSS_CFG_OFFSET + 0x40) = 0x0;// Internal pinmux /* MII Config */ HWREG(SOC_PRUICSS1_REGS + SOC_PRUICSS_MII_OFFSET + 0x0) = 0x1;//RXCFG0 /* RX_L2 – 0x0, disable RX_ENABLE – 0x1*/ HWREG(SOC_PRUICSS1_REGS + SOC_PRUICSS_MII_OFFSET + 0x10) = 0x60400101; //TXCFG0 /* TX_CLK_DELAY – 0x6 TX_START_DELAY – 0x40 TX_MUX_SEL – 0x1 (Data from pru1) TX_ENABLE – 0x1*/ MMUConfigAndEnable(); CacheEnable(CACHE_ALL); while(1) { MDIO_WRITE(0, 0x7100);//write to the LAN8710 Regs (set the LOOPBACK mode) Delay(200000000); char temp[1]; ConsoleUtilsPrintf("\n\nPress 1 to start the programm\n\n"); ConsoleUtilsGets(temp, 3); ConsoleUtilsPrintf("\nSTART\n"); int reg1 = MDIO_READ(0x1); );//read LAN8710 Status if ((reg1&0x4)&&0x4)//Link status UP { ConsoleUtilsPrintf("LINK is UP\n"); PRUMemLoad(PRU_ICSS1, PRU1_IRAM, 0, sizeof(LED1_INST), (unsigned int*)LED1_INST); PRUMemLoad(PRU_ICSS1, PRU1_DRAM, 0, sizeof(LED1_DATA), (unsigned int*)LED1_DATA); ConsoleUtilsPrintf("\nRunning PRUs...\n\n"); PRUEnable(PRU_ICSS1, PRU1); int i, j; for (j=0; j<3; j++) { ConsoleUtilsPrintf("data = "); for (i=0; i<7; i++) { data_from_PRU[i] = HWREG(SOC_PRUICSS1_REGS + SOC_PRUICSS_SHARED_RAM_OFFSET + 0x4*i); ConsoleUtilsPrintf("%x ", data_from_PRU[i]); } ConsoleUtilsPrintf("\n"); Delay(150000000); } int rx = HWREG(SOC_PRUICSS1_REGS + SOC_PRUICSS_MII_OFFSET + 0x0); int tx = HWREG(SOC_PRUICSS1_REGS + SOC_PRUICSS_MII_OFFSET + 0x10); ConsoleUtilsPrintf("cfg: rx = %x tx = %x\n", rx, tx);//status do not changed PRUHalt(PRU_ICSS1, PRU1); } else ConsoleUtilsPrintf("LINK is DOWN\n"); } while(1); } void PRUCapePinmux(void) { HWREG(SOC_CONTROL_REGS + CONTROL_CONF_LCD_DATA(0)) = AM335X_PIN_INPUT | CONTROL_CONF_MUXMODE(2);//clk HWREG(SOC_CONTROL_REGS + CONTROL_CONF_LCD_DATA(1)) =AM335X_PIN_OUTPUT|CONTROL_CONF_MUXMODE(2);//txen HWREG(SOC_CONTROL_REGS + CONTROL_CONF_LCD_DATA(2)) = AM335X_PIN_OUTPUT | CONTROL_CONF_MUXMODE(2);//tx HWREG(SOC_CONTROL_REGS + CONTROL_CONF_LCD_DATA(3)) = AM335X_PIN_OUTPUT | CONTROL_CONF_MUXMODE(2);//tx HWREG(SOC_CONTROL_REGS + CONTROL_CONF_LCD_DATA(4)) = AM335X_PIN_OUTPUT | CONTROL_CONF_MUXMODE(2);//tx HWREG(SOC_CONTROL_REGS + CONTROL_CONF_LCD_DATA(5)) = AM335X_PIN_OUTPUT | CONTROL_CONF_MUXMODE(2);//tx HWREG(SOC_CONTROL_REGS + CONTROL_CONF_LCD_DATA(8)) = AM335X_PIN_INPUT | CONTROL_CONF_MUXMODE(5);//rx HWREG(SOC_CONTROL_REGS + CONTROL_CONF_LCD_DATA(9)) = AM335X_PIN_INPUT | CONTROL_CONF_MUXMODE(5);//rx HWREG(SOC_CONTROL_REGS + CONTROL_CONF_LCD_DATA(10)) = AM335X_PIN_INPUT | CONTROL_CONF_MUXMODE(5);//rx HWREG(SOC_CONTROL_REGS + CONTROL_CONF_LCD_DATA(11)) = AM335X_PIN_INPUT | CONTROL_CONF_MUXMODE(5);//rx HWREG(SOC_CONTROL_REGS + CONTROL_CONF_LCD_DATA(13)) = AM335X_PIN_INPUT | CONTROL_CONF_MUXMODE(5);//rxer HWREG(SOC_CONTROL_REGS + CONTROL_CONF_LCD_DATA(15)) = AM335X_PIN_INPUT |CONTROL_CONF_MUXMODE(5);//rxdv HWREG(SOC_CONTROL_REGS + CONTROL_CONF_LCD_PCLK) = AM335X_PIN_INPUT | CONTROL_CONF_MUXMODE(2);//crs HWREG(SOC_CONTROL_REGS + CONTROL_CONF_LCD_DATA(14)) = AM335X_PIN_INPUT | CONTROL_CONF_MUXMODE(5);//clk //****************************************************************************** // MDIO by GPIO //****************************************************************************** HWREG(SOC_CONTROL_REGS + CONTROL_CONF_GPMC_AD(12)) = 0x3f;//mdio_clk HWREG(SOC_CONTROL_REGS + CONTROL_CONF_GPMC_AD(14)) = 0x3f;//mdio_clk }
Using the oscilloscope I can see the MII correctly signals on the mii_rxd[0-3], mii_txd[0-3], mii_rx_clk, mii_tx_clk, mii_tx_en, mii_rx_dv pins. I do not understand how I must connect the mii_rx_link (I do not connect it now). mii_rx_er signal is always “0”. mii_rx_col signal using only at the RMII mode.
When I read the __R31 register I always get 0x1000000 (1<<24 - at the GPI_MII mode it must be CRC error, spruh73p, Table4_32). Another strange situation become when I write the following code:
rx_data = __R31; // rx_data = 0x1000000; //if I not comment this line, program will work further, otherwise hung after “if condition” i f (rx_data == 0x1000000) CT_SHAREDMEM.mem[3] = 0x2; else CT_SHAREDMEM.mem[3] = 0x1; __delay_cycles(400); CT_SHAREDMEM.mem[4] = 0x55;//this line work only if not comment line “rx_data = 0x1000000;”
I do not understand why it hung. I try to compile with different optimization flags. O0 do not work, O1,O2 – no difference.
So, what the wrong? I do:
- Internal pru pinmux
- Global pinmux
- Set PRU_MII_RT registers
- Set PRU_CFG registers
- Correctly send the packet using the PRU_MII_RT
- Get correct signals on mii_rx pins (look using the oscilloscope)
- See that at the PRU_MII_RT_PRS0 register _Current state of pr1_mii0_crs = 0x1 (if I send data in cycle)
- Can not read anything information about the packet (not data, not status), always read 0x1000000 (1<<24).
- I try to reset rx (1<<18 command), rx_pop16 (1<<17 command)