📄 lan91c111.c
字号:
put_reg(LAN91C111_TCR, 0x1); put_reg(LAN91C111_MMU_COMMAND, 0xc0); delay(30); release_transmit_pack(); put_reg(LAN91C111_INTERRUPT, 0x2 ); }*//*static voidrelease_transmit_pack(){ put_reg(LAN91C111_MMU_COMMAND, 0xa0); while(get_reg(LAN91C111_MMU_COMMAND) & 0x1) {printf("\nrelease_transmit_pack()\n"); };}*/void test_get_reg(){ //BANK 0 printf("Bank 0 register \n"); printf("i 0x%08x is 0x%08x\n", LAN91C111_TCR, get_reg(LAN91C111_TCR) ); printf("i 0x%08x is 0x%08x\n", LAN91C111_EPH_STATUS, get_reg(LAN91C111_EPH_STATUS)); printf("i 0x%08x is 0x%08x\n", LAN91C111_RCR, get_reg(LAN91C111_RCR)); printf("i 0x%08x is 0x%08x\n", LAN91C111_COUNTER, get_reg(LAN91C111_COUNTER)); printf("i 0x%08x is 0x%08x\n", LAN91C111_MIR, get_reg(LAN91C111_MIR)); printf("i 0x%08x is 0x%08x\n", LAN91C111_RPCR, get_reg(LAN91C111_RPCR)); printf("i 0x%08x is 0x%08x\n", LAN91C111_RESERVED, get_reg(LAN91C111_RESERVED)); printf("i 0x%08x is 0x%08x\n", LAN91C111_BANK, get_reg(LAN91C111_BANK)); //BANK 1 printf("Bank 1 register \n"); printf("i 0x%08x is 0x%08x\n", LAN91C111_CONFIG, get_reg(LAN91C111_CONFIG) ); printf("i 0x%08x is 0x%08x\n", LAN91C111_BASE, get_reg(LAN91C111_BASE)); printf("i 0x%08x is 0x%08x\n", LAN91C111_IA01, get_reg(LAN91C111_IA01)); printf("i 0x%08x is 0x%08x\n", LAN91C111_IA23, get_reg(LAN91C111_IA23)); printf("i 0x%08x is 0x%08x\n", LAN91C111_IA45, get_reg(LAN91C111_IA45)); printf("i 0x%08x is 0x%08x\n", LAN91C111_GENERAL, get_reg(LAN91C111_GENERAL)); printf("i 0x%08x is 0x%08x\n", LAN91C111_CONTROL, get_reg(LAN91C111_CONTROL)); printf("i 0x%08x is 0x%08x\n", LAN91C111_BANK1, get_reg(LAN91C111_BANK1)); //BANK 2 printf("Bank2 register \n"); printf("i 0x%08x is 0x%08x\n", LAN91C111_MMU_COMMAND, get_reg(LAN91C111_MMU_COMMAND)); printf("i 0x%08x is 0x%08x\n", LAN91C111_PNR, get_reg(LAN91C111_PNR)); printf("i 0x%08x is 0x%08x\n", LAN91C111_ARR, get_reg(LAN91C111_ARR)); printf("i 0x%08x is 0x%08x\n", LAN91C111_FIFO_PORTS, get_reg(LAN91C111_FIFO_PORTS)); printf("i 0x%08x is 0x%08x\n", LAN91C111_POINTER, get_reg(LAN91C111_POINTER)); // printf("i 0x%08x is 0x%08x\n", LAN91C111_DATA_HIGH, get_reg(LAN91C111_DATA_HIGH)); // printf("i 0x%08x is 0x%08x\n", LAN91C111_DATA_LOW, get_reg(LAN91C111_DATA_LOW)); printf("i 0x%08x is 0x%08x\n", LAN91C111_INTERRUPT, get_reg(LAN91C111_INTERRUPT)); printf("i 0x%08x is 0x%08x\n", LAN91C111_INTERRUPT_M, get_reg(LAN91C111_INTERRUPT_M)); printf("i 0x%08x is 0x%08x\n", LAN91C111_BANK2, get_reg(LAN91C111_BANK2)); //BANK 3 printf("Bank 3 register \n"); printf("i 0x%08x is 0x%08x\n", LAN91C111_MT01, get_reg(LAN91C111_MT01)); printf("i 0x%08x is 0x%08x\n", LAN91C111_MT23, get_reg(LAN91C111_MT23)); printf("i 0x%08x is 0x%08x\n", LAN91C111_MT45, get_reg(LAN91C111_MT45)); printf("i 0x%08x is 0x%08x\n", LAN91C111_MGMT, get_reg(LAN91C111_MGMT)); printf("i 0x%08x is 0x%08x\n", LAN91C111_REVISION, get_reg(LAN91C111_REVISION)); printf("i 0x%08x is 0x%08x\n", LAN91C111_ERCV, get_reg(LAN91C111_ERCV)); printf("i 0x%08x is 0x%08x\n", LAN91C111_BANK3, get_reg(LAN91C111_BANK3)); //PHY Register /* printf("PHY register \n"); printf("i 0x%08x is 0x%08x\n", LAN91C111_PHY_CONTROL, lan91c111_read_phy(0, LAN91C111_PHY_CONTROL)); printf("i 0x%08x is 0x%08x\n", LAN91C111_PHY_STATUS, lan91c111_read_phy(0, LAN91C111_PHY_STATUS)); printf("i 0x%08x is 0x%08x\n", LAN91C111_PHY_ID1, lan91c111_read_phy(0, LAN91C111_PHY_ID1)); printf("i 0x%08x is 0x%08x\n", LAN91C111_PHY_ID2, lan91c111_read_phy(0, LAN91C111_PHY_ID2)); printf("i 0x%08x is 0x%08x\n", LAN91C111_PHY_AUTO_AD, lan91c111_read_phy(0,LAN91C111_PHY_AUTO_AD)); printf("i 0x%08x is 0x%08x\n", LAN91C111_PHY_AUTO_CAP, lan91c111_read_phy(0, LAN91C111_PHY_AUTO_CAP)); printf("i 0x%08x is 0x%08x\n", LAN91C111_PHY_CFG_1, lan91c111_read_phy(0, LAN91C111_PHY_CFG_1)); printf("i 0x%08x is 0x%08x\n", LAN91C111_PHY_CFG_2, lan91c111_read_phy(0, LAN91C111_PHY_CFG_2)); printf("i 0x%08x is 0x%08x\n", LAN91C111_PHY_STATUS_OUT, lan91c111_read_phy(0, LAN91C111_PHY_STATUS_OUT)); printf("i 0x%08x is 0x%08x\n", LAN91C111_PHY_MASK, lan91c111_read_phy(0, LAN91C111_PHY_MASK)); */ printf("Test end \n");}void print_packet(void * packet, int len ){ int i=0; char * offset=(char * )packet; offset = (char * )packet; printf("\nprintf_pack() execute\n"); for(i=0; i<len; i++) printf("printf_pack():pack 0x%04x is 0x%08x\n", i, *offset++ ); printf("printf_pack() finished\n");}void smc_wait_mmu_busy(){ unsigned long timeout= 0x1000; while(get_reg(LAN91C111_MMU_COMMAND) & 0x1) { timeout--; if(!timeout) break; }}static void release_receive_pack(){ put_reg(LAN91C111_MMU_COMMAND, 0x80); while(get_reg(LAN91C111_MMU_COMMAND) & 0x1) {printf("\nrelease_receive_pack()\n"); };}static voidlan91c111_deallocate_txpacket(void){ unsigned short resultcode; unsigned char intstatus; //get the transmit status put_reg(LAN91C111_POINTER, (0x1<<13)); resultcode = get_reg(LAN91C111_DATA_HIGH); //clear the statistics register get_reg(LAN91C111_COUNTER); //re_enable the txena in the transmit put_reg(LAN91C111_TCR, get_reg(LAN91C111_TCR) | 0x1 | 0x80); //re_enable the rec_en put_reg(LAN91C111_RCR, get_reg(LAN91C111_RCR) | 0x100 ); //release the memory put_reg(LAN91C111_MMU_COMMAND, (0x5<<5) ); //wait for the request complete while( !get_reg(LAN91C111_MMU_COMMAND) & 0x1 ) { printf("lan91c111_deallocate_txpacket()waitting mmu succeed \n "); } //Get the Interrupt Status Reg intstatus = get_reg(LAN91C111_INTERRUPT); if (intstatus & (0x1<<1)) { put_reg(LAN91C111_INTERRUPT, (intstatus | (0x1<<1) )); }}static int lan91c111_allocate_txpacket(unsigned short * packethandle ){ unsigned char status, tempvalue; lan91c111_deallocate_txpacket(); put_reg(LAN91C111_MMU_COMMAND, (0x1<<5)); while(!((status = get_reg(LAN91C111_INTERRUPT)) & (0x1<<3))) { // printf("lan91c111_allocate_txpacket() waitting the allow succeed \n"); } if(status & (0x1<<3)) { tempvalue = get_reg(LAN91C111_ARR); *packethandle = tempvalue & 0x7; } return(0);}static bool lan91c111_init(void){ uint16 *mac; unsigned short val=0; unsigned int * ioregsp; // unsigned long nx_timer=0; // char link=1; ioregsp = (unsigned int *)base; //assert whether the Eth port can access val = get_reg(LAN91C111_BANK); if ((val & 0xff00) == 0x3300) assert(" Eth port can access, the base address is 0x%08x\n ", LAN91C111_BASE_ADDR); else { failed(" Eth port can't access,check you Eth chip\n"); return false; } //assert whethe the Eth chip is LAN91C111 val = get_reg(LAN91C111_REVISION); if ((val & 0xfff0) == LAN91C111_CHIP_ID) assert("Eth chip is LAN91C111\n"); else { failed("Eth chip is not LAN91C111\n "); return false; } //Reset chip put_reg(LAN91C111_RCR, RCR_SOFT_RST); udelay(20); // put_reg(LAN91C111_RCR, 0); //edit put_reg(LAN91C111_CONFIG, 0x8000 ); val = get_reg(LAN91C111_CONFIG); put_reg(LAN91C111_CONFIG, val | 0x1000 ); sec_sleep(1); put_reg(LAN91C111_RCR, 0); put_reg(LAN91C111_TCR, 0); mac = (uint16*)setup->myhaddr; put_reg(LAN91C111_IA01, *mac++); put_reg(LAN91C111_IA23, *mac++); put_reg(LAN91C111_IA45, *mac++); val = get_reg(LAN91C111_CONTROL); put_reg(LAN91C111_CONTROL, val | 0x0800); // get rid of the PHY isolated mode val = lan91c111_read_phy(0, LAN91C111_PHY_CONTROL); // printf("phy control is 0x%08x\n", val); val &= ~PHY_CONTROL_MII_DIS; lan91c111_write_phy(0, LAN91C111_PHY_CONTROL, val); // printf("PHY control is 0x%08x\n", lan91c111_read_phy(0, LAN91C111_PHY_CONTROL)); //set autonegotiation put_reg(LAN91C111_RPCR, RPCR_LSA_0 | RPCR_LSB_6); //RPCR_ANEG // printf("RPCR IS 0x%08x\n", get_reg(LAN91C111_RPCR)); val = lan91c111_read_phy(0, LAN91C111_PHY_CONTROL); val |= PHY_CONTROL_ANEG_EN; lan91c111_write_phy(0, LAN91C111_PHY_CONTROL, val); //Disable interrupt put_reg(LAN91C111_INTERRUPT_M, 0x0); //Free all memory allocations put_reg(LAN91C111_MMU_COMMAND, RESET_MMU_TO_INIT); smc_wait_mmu_busy(); // nx_timer = clock() + CLOCKS_PER_SEC; // while(clock()<nx_timer ){} ; //Disable interrupt // put_reg(LAN91C111_INTERRUPT, 0x0); // put_reg(LAN91C111_INTERRUPT_M, 0x0); val = get_reg(LAN91C111_INTERRUPT); val &= (INTERRUPT_MDINT | INTERRUPT_ERCV_INT | INTERRUPT_RX_OVRN_INT | INTERRUPT_TX_EMPTY_INT | INTERRUPT_TX_INT ); put_reg(LAN91C111_INTERRUPT, val); //set the Receiver Control Register // put_reg(LAN91C111_RCR, RCR_ABORT_ENB | RCR_STRIP_CRC | RCR_RXEN | RCR_ALMUL); put_reg(LAN91C111_RCR, RCR_RXEN | 0x200); //set the Transmit Control Register put_reg(LAN91C111_TCR, TCR_PAD_EN | TCR_TXENA); //set the Control Register put_reg(LAN91C111_CONTROL, 0); // sec_sleep(1); /* val=0; //delay(30); nx_timer = clock() + CLOCKS_PER_SEC*2; while(!((val = lan91c111_read_phy(0, LAN91C111_PHY_STATUS)) & PHY_STATUS_ANEG_ACK )) { if (clock() > nx_timer ) { link = 0; printf(" The Line is not connetc, please the cable\n"); break; } } */ /* if (link) {nx_timer = clock() + CLOCKS_PER_SEC; while(clock()<nx_timer ) {} val = get_reg(LAN91C111_RPCR); put_reg(LAN91C111_RPCR, val & (~(RPCR_ANEG))); } */ return true;}static void lan91c111_exit(void){}//This function is used for transmit the packet, be care for allocate for data area which for transmissionstatic bool lan91c111_send_packet(void *packet, int len){ unsigned short control_word=0; unsigned short *source = (unsigned short *)packet; unsigned short plen = len>>1; unsigned char last_data_byte=0; unsigned short framehandle=0; unsigned char intstatus; unsigned short resultcode; // printf("\nlan91c111_send_packet() begin \n"); // printf("lan91c111_send_packet()len is 0x%08x\n", len); // print_packet(packet, len ); // printf("\nlan91c111_send_packet() finish\n"); //allocate the area fo transmit lan91c111_allocate_txpacket(&framehandle); put_reg(LAN91C111_PNR, (unsigned char)framehandle); // //Enable the transmit put_reg(LAN91C111_TCR, get_reg(LAN91C111_TCR) | 0x1 | 0x80); put_reg(LAN91C111_POINTER, 0x4000); //write the status word,it will be write by MAC put_data(0x0000); //write the BYTE COUNT put_data( len + 6 ); //write the data area while(plen--) { put_data(*source++); } //write the control word; if(len & 1) { last_data_byte = *(unsigned char *)source & 0xff ; control_word = last_data_byte | ( ((0x1<<4) | (0x1<<5))<<8 ) ; } else control_word = ((0x1<<4)<<8); put_data(control_word) ; // put_reg(LAN91C111_TCR, 0x01 | 0x80 ); put_reg(LAN91C111_MMU_COMMAND, 0x00c0); while(!((intstatus = get_reg(LAN91C111_INTERRUPT)) & (0x1<<2)) ) {//printf("lan91c111_transmit_packet(): is not already transmit\n "); } if ( intstatus & (0x1<<2) ) { put_reg(LAN91C111_INTERRUPT, intstatus | (0x1<<2)); } if( intstatus & (0x1<<1) ) { put_reg(LAN91C111_INTERRUPT, intstatus | (0x1<<1)); resultcode = get_reg( LAN91C111_FIFO_PORTS ); if (!(resultcode & (0x1<<7) )) put_reg(LAN91C111_PNR, (unsigned char)resultcode ); } get_reg(LAN91C111_COUNTER); return true;}//This function is be used for receive packet, be care for the timing.static int lan91c111_recv_packet(void){ unsigned int val=0; unsigned int i=0; unsigned short status=0, lenth=0; uchar rxbuff[1024], *point = rxbuff + 2; unsigned char * offset; unsigned int count=0, last=0; unsigned long s_l=0; unsigned char control_byte=0; offset = point; if (get_reg(LAN91C111_INTERRUPT) & 0x01) { // printf("lan91c111_recv_pack() begin\n"); val = get_reg(LAN91C111_FIFO_PORTS); put_reg(LAN91C111_POINTER, 0xe000); //get status and lenth; val = get_data_32(); s_l = val; status = val & 0xffff; lenth = (val>>16) - 6 ; //is byte counter; count = lenth / 4 ; last = lenth % 4 ; for(i=0; i<count; i++) { val = get_data_32(); *offset++ = (val & 0xff); *offset++ = (val & 0xff00)>>8; *offset++ = (val & 0xff0000)>>16; *offset++ = (val & 0xff000000)>>24; } //get the last data and control word val = get_data_32(); if (last == 0) { *offset++ = (val & 0xff); // the lower of the control word control_byte = (val & 0xff00)>>8; } else if(last == 1) { *offset++ = (val & 0xff); *offset++ = (val & 0xff00)>>8; //the lower of the contorl word control_byte = (val & 0xff0000)>>16; } else if(last == 2) { *offset++ = (val & 0xff); *offset++ = (val & 0xff00)>>8; *offset++ = (val & 0xff0000)>>16; //the lower of the contorl word control_byte = (val & 0xff000000)>>24; } else if(last == 3) { *offset++ = (val & 0xff); *offset++ = (val & 0xff00)>>8; *offset++ = (val & 0xff0000)>>16; *offset++ = (val & 0xff000000)>>24; //the lower of the control word val = get_data_32(); control_byte = (val & 0xff); } if(control_byte & 0x20) lenth++; /* if(control_byte & 0x10) printf("lan91c111_rec_pack(): CRC ERROR\n" ); */ //printf the resutl; //print_packet((void *)point, lenth); //printf("lan91c111_recv_pack() finish\n"); netif_rx((void *)point, lenth); release_receive_pack(); timeout = clock() + (CLOCKS_PER_SEC*2); return true; } return false;}static void lan91c111_enable(void){ return;}static void lan91c111_disable(void){ return;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -