//****************************************************************************************** // PIC32MX120F032B Sample Program // Project : // Program Name : // Programer : // Create date : Version 1.0 H25.03.16 // History : // Language : MPLAB C32 //****************************************************************************************** // Description // 1.Basic configuration // (1)OSC : Internal OSC PLL 40MHz // (2)UART Propaty : 9600BPS, Assign UART Pin : RX(PB13),TX(PB15) // (3)A/D Converter : AN0 // 2.Basic Device Settings // (1)Lan controller ENC28J60 // RB14:INT (I) // RB12:SO (I) // RB11:SI (O) // RB10:SCK (O) // RB9 :CS (O) // RB8 :RESET(O) //****************************************************************************************** //#include #include // // Define configration words // #pragma config PMDL1WAY = OFF //Peripheral Module Disable Configuration:Allow multiple reconfigurations #pragma config IOL1WAY = OFF //Peripheral Pin Select Configuration:Allow multiple reconfigurations #pragma config FUSBIDIO = OFF //USB USID Selection:Controlled by Port Function #pragma config FVBUSONIO = OFF //USB VBUS ON Selection:Controlled by Port Function //#pragma config FPLLIDIV= DIV_1 //PLL Input Divider:1x Divider (DIV_1,DIV_2,DIV_3,DIV_4,DIV_5,DIV_6,DIV_10,DIV_12) #pragma config FPLLIDIV = DIV_2 //#pragma config FPLLMUL = MUL_15 //PLL Multiplier:15x Multiplier(MUL_15,MUL_16,MUL_17,MUL_18,MUL_19,MUL_20,MUL_21,MUL_24) #pragma config FPLLMUL = MUL_20 //#pragma config FPLLODIV= DIV_1 //System PLL Output Clock Divider:PLL Divide by 1(DIV_1,DIV_2,DIV_4,DIV_8,DIV_16,DIV_32,DIV_64,DIV_256) #pragma config FPLLODIV = DIV_2 //#pragma config FNOSC = FRC //Oscillator Selection Bits:Fast RC Osc (FRC) (FRC,FRCPLL,PRI,PRIPLL,SOSC,LPRC,FRCDIV16,FRCDIV) #pragma config FNOSC = FRCPLL #pragma config FSOSCEN = OFF //Secondary Oscillator Enable:Disabled #pragma config IESO = OFF //Internal/External Switch Over:Disabled #pragma config POSCMOD = OFF //Primary Oscillator Configuration:Primary osc disabled (EC,XT,HS,OFF) #pragma config OSCIOFNC = OFF //CLKO Output Signal Active on the OSCO Pin::Disabled #pragma config FPBDIV = DIV_1 //Peripheral Clock Divisor:Pb_Clk is Sys_Clk/1 (DIV_1,DIV_2,DIV_4,DIV_8) #pragma config FCKSM = CSDCMD //Clock Switching and Monitor Selection:Clock Switch Disable, FSCM Disabled (CSECME,CSECMD,CSDCMD) #pragma config WDTPS = PS1 //Watchdog Timer Postscaler:1:1 (PS1,,,,PS1048576) #pragma config WINDIS = OFF //Watchdog Timer Window Enable:Watchdog Timer is in Non-Window Mode #pragma config FWDTEN = OFF //Watchdog Timer Enable:WDT Disabled (SWDTEN Bit Controls) #pragma config FWDTWINSZ = WINSZ_50//Watchdog Timer Window Size:Window Size is 50% (WINSZ_75,WINSZ_50,WINSZ_37,WISZ_25) #pragma config DEBUG = OFF //Background Debugger Enable:Debugger is Disabled #pragma config JTAGEN = OFF //JTAG Enable:JTAG Disabled #pragma config ICESEL = RESERVED//ICE/ICD Comm Channel Select:Reserved (RESERVED,ICS_PGx3,ICS_PGx2,ICS_PGx1) #pragma config PWP = OFF //Program Flash Write Protect: #pragma config BWP = OFF //Boot Flash Write Protect bit: #pragma config CP = OFF //Code Protect: // // SPI Instruction set for the ENC28J60 // #define PI_ENC28CMD_RCR 0b00000000 #define PI_ENC28CMD_RBM 0b00111010 #define PI_ENC28CMD_WCR 0b01000000 #define PI_ENC28CMD_WBM 0b01111010 #define PI_ENC28CMD_BFS 0b10000000 #define PI_ENC28CMD_BFC 0b10100000 #define PI_ENC28CMD_SRC 0b11111111 // // ENC28J60 Control register address // #define PI_REGADDR_ERDPTL 0x00 #define PI_REGADDR_EHT0 0x00 #define PI_REGADDR_MACON1 0x00 #define PI_REGADDR_MAADR5 0x00 #define PI_REGADDR_ERDPTH 0x01 #define PI_REGADDR_EHT1 0x01 #define PI_REGADDR_MAADR6 0x01 #define PI_REGADDR_EWRPTL 0x02 #define PI_REGADDR_EHT2 0x02 #define PI_REGADDR_MACON3 0x02 #define PI_REGADDR_MAADR3 0x02 #define PI_REGADDR_EWRPTH 0x03 #define PI_REGADDR_EHT3 0x03 #define PI_REGADDR_MACON4 0x03 #define PI_REGADDR_MAADR4 0x03 #define PI_REGADDR_ETXSTL 0x04 #define PI_REGADDR_EHT4 0x04 #define PI_REGADDR_MABBIPG 0x04 #define PI_REGADDR_MAADR1 0x04 #define PI_REGADDR_ETXSTH 0x05 #define PI_REGADDR_EHT5 0x05 #define PI_REGADDR_MAADR2 0x05 #define PI_REGADDR_ETXNDL 0x06 #define PI_REGADDR_EHT6 0x06 #define PI_REGADDR_MAIPGL 0x06 #define PI_REGADDR_EBSTSD 0x06 #define PI_REGADDR_ETXNDH 0x07 #define PI_REGADDR_EHT7 0x07 #define PI_REGADDR_MAIPGH 0x07 #define PI_REGADDR_EBSTCON 0x07 #define PI_REGADDR_ERXSTL 0x08 #define PI_REGADDR_EPMM0 0x08 #define PI_REGADDR_MACLCON1 0x08 #define PI_REGADDR_EBSTCSL 0x08 #define PI_REGADDR_ERXSTH 0x09 #define PI_REGADDR_EPMM1 0x09 #define PI_REGADDR_MACLCON2 0x09 #define PI_REGADDR_EBSTCSH 0x09 #define PI_REGADDR_ERXNDL 0x0A #define PI_REGADDR_EPMM2 0x0A #define PI_REGADDR_MAMXFLL 0x0A #define PI_REGADDR_MISTAT 0x0A #define PI_REGADDR_ERXNDH 0x0B #define PI_REGADDR_EPMM3 0x0B #define PI_REGADDR_MAMXFLH 0x0B #define PI_REGADDR_ERXRDPTL 0x0C #define PI_REGADDR_EPMM4 0x0C #define PI_REGADDR_ERXRDPTH 0x0D #define PI_REGADDR_EPMM5 0x0D #define PI_REGADDR_ERXWRPTL 0x0E #define PI_REGADDR_EPMM6 0x0E #define PI_REGADDR_ERXWRPTH 0x0F #define PI_REGADDR_EPMM7 0x0F #define PI_REGADDR_EDMASTL 0x10 #define PI_REGADDR_EPMCSL 0x10 #define PI_REGADDR_EDMASTH 0x11 #define PI_REGADDR_EPMCSH 0x11 #define PI_REGADDR_EDMANDL 0x12 #define PI_REGADDR_MICMD 0x12 #define PI_REGADDR_EREVID 0x12 #define PI_REGADDR_EDMANDH 0x13 #define PI_REGADDR_EDMADSTL 0x14 #define PI_REGADDR_EPMOL 0x14 #define PI_REGADDR_MIREGADR 0x14 #define PI_REGADDR_EDMADSTH 0x15 #define PI_REGADDR_EPMOH 0x15 #define PI_REGADDR_ECOCON 0x15 #define PI_REGADDR_EDMACSL 0x16 #define PI_REGADDR_MIWRL 0x16 #define PI_REGADDR_EDMACSH 0x17 #define PI_REGADDR_MIWRH 0x17 #define PI_REGADDR_EFLOCON 0x17 #define PI_REGADDR_ERXFCON 0x18 #define PI_REGADDR_MIRDL 0x18 #define PI_REGADDR_EPAUSL 0x18 #define PI_REGADDR_EPKTCNT 0x19 #define PI_REGADDR_MIRDH 0x19 #define PI_REGADDR_EPAUSH 0x19 #define PI_REGADDR_EIE 0x1B #define PI_REGADDR_EIR 0x1C #define PI_REGADDR_ESTAT 0x1D #define PI_REGADDR_ECON2 0x1E #define PI_REGADDR_ECON1 0x1F // //Define Memory bank // #define PI_BANK0 (unsigned char)0 #define PI_BANK1 (unsigned char)1 #define PI_BANK2 (unsigned char)2 #define PI_BANK3 (unsigned char)3 // // // #define PI_REGBANK_ERDPTL PI_BANK0 #define PI_REGBANK_EHT0 PI_BANK1 #define PI_REGBANK_MACON1 PI_BANK2 #define PI_REGBANK_MAADR5 PI_BANK3 #define PI_REGBANK_ERDPTH PI_BANK0 #define PI_REGBANK_EHT1 PI_BANK1 #define PI_REGBANK_MAADR6 PI_BANK3 #define PI_REGBANK_EWRPTL PI_BANK0 #define PI_REGBANK_EHT2 PI_BANK1 #define PI_REGBANK_MACON3 PI_BANK2 #define PI_REGBANK_MAADR3 PI_BANK3 #define PI_REGBANK_EWRPTH PI_BANK0 #define PI_REGBANK_EHT3 PI_BANK1 #define PI_REGBANK_MACON4 PI_BANK2 #define PI_REGBANK_MAADR4 PI_BANK3 #define PI_REGBANK_ETXSTL PI_BANK0 #define PI_REGBANK_EHT4 PI_BANK1 #define PI_REGBANK_MABBIPG PI_BANK2 #define PI_REGBANK_MAADR1 PI_BANK3 #define PI_REGBANK_ETXSTH PI_BANK0 #define PI_REGBANK_EHT5 PI_BANK1 #define PI_REGBANK_MAADR2 PI_BANK3 #define PI_REGBANK_ETXNDL PI_BANK0 #define PI_REGBANK_EHT6 PI_BANK1 #define PI_REGBANK_MAIPGL PI_BANK2 #define PI_REGBANK_EBSTSD PI_BANK3 #define PI_REGBANK_ETXNDH PI_BANK0 #define PI_REGBANK_EHT7 PI_BANK1 #define PI_REGBANK_MAIPGH PI_BANK2 #define PI_REGBANK_EBSTCON PI_BANK3 #define PI_REGBANK_ERXSTL PI_BANK0 #define PI_REGBANK_EPMM0 PI_BANK1 #define PI_REGBANK_MACLCON1 PI_BANK2 #define PI_REGBANK_EBSTCSL PI_BANK3 #define PI_REGBANK_ERXSTH PI_BANK0 #define PI_REGBANK_EPMM1 PI_BANK1 #define PI_REGBANK_MACLCON2 PI_BANK2 #define PI_REGBANK_EBSTCSH PI_BANK3 #define PI_REGBANK_ERXNDL PI_BANK0 #define PI_REGBANK_EPMM2 PI_BANK1 #define PI_REGBANK_MAMXFLL PI_BANK2 #define PI_REGBANK_MISTAT PI_BANK3 #define PI_REGBANK_ERXNDH PI_BANK0 #define PI_REGBANK_EPMM3 PI_BANK1 #define PI_REGBANK_MAMXFLH PI_BANK2 #define PI_REGBANK_ERXRDPTL PI_BANK0 #define PI_REGBANK_EPMM4 PI_BANK1 #define PI_REGBANK_ERXRDPTH PI_BANK0 #define PI_REGBANK_EPMM5 PI_BANK1 #define PI_REGBANK_ERXWRPTL PI_BANK0 #define PI_REGBANK_EPMM6 PI_BANK1 #define PI_REGBANK_ERXWRPTH PI_BANK0 #define PI_REGBANK_EPMM7 PI_BANK1 #define PI_REGBANK_EDMASTL PI_BANK0 #define PI_REGBANK_EPMCSL PI_BANK1 #define PI_REGBANK_EDMASTH PI_BANK0 #define PI_REGBANK_EPMCSH PI_BANK1 #define PI_REGBANK_EDMANDL PI_BANK0 #define PI_REGBANK_MICMD PI_BANK2 #define PI_REGBANK_EREVID PI_BANK3 #define PI_REGBANK_EDMANDH PI_BANK0 #define PI_REGBANK_EDMADSTL PI_BANK0 #define PI_REGBANK_EPMOL PI_BANK1 #define PI_REGBANK_MIREGADR PI_BANK2 #define PI_REGBANK_EDMADSTH PI_BANK0 #define PI_REGBANK_EPMOH PI_BANK1 #define PI_REGBANK_ECOCON PI_BANK3 #define PI_REGBANK_EDMACSL PI_BANK0 #define PI_REGBANK_MIWRL PI_BANK2 #define PI_REGBANK_EDMACSH PI_BANK0 #define PI_REGBANK_MIWRH PI_BANK2 #define PI_REGBANK_EFLOCON PI_BANK3 #define PI_REGBANK_ERXFCON PI_BANK1 #define PI_REGBANK_MIRDL PI_BANK2 #define PI_REGBANK_EPAUSL PI_BANK3 #define PI_REGBANK_EPKTCNT PI_BANK1 #define PI_REGBANK_MIRDH PI_BANK2 #define PI_REGBANK_EPAUSH PI_BANK3 #define PI_REGBANK_EIE PI_BANK0 #define PI_REGBANK_EIR PI_BANK0 #define PI_REGBANK_ESTAT PI_BANK0 #define PI_REGBANK_ECON2 PI_BANK0 #define PI_REGBANK_ECON1 PI_BANK0 // // ENC28J60 PHY register address // #define PI_PHYADDR_PHCON1 0x00 #define PI_PHYADDR_PHSTAT1 0x01 #define PI_PHYADDR_PHID1 0x02 #define PI_PHYADDR_PHID2 0x03 #define PI_PHYADDR_PHCON2 0x10 #define PI_PHYADDR_PHSTAT2 0x11 #define PI_PHYADDR_PHIE 0x12 #define PI_PHYADDR_PHIR 0x13 #define PI_PHYADDR_PHLCON 0x14 // //Define Local MAC address // #define PI_MAC_1 0x00 #define PI_MAC_2 0x01 #define PI_MAC_3 0x02 #define PI_MAC_4 0x03 #define PI_MAC_5 0x04 #define PI_MAC_6 0x05 // //Define Parameter // #define PI_LINE_MAX 20 #define PI_STATUS_L 1 #define PI_STATUS_H 2 #define PI_STATUS_PKT_SET 3 #define PI_STATUS_PKT_EMPTY 4 #define PI_NORMAL 5 #define PI_FAILURE 6 #define PI_SEND_MAX 1514 #define PI_DEFINE_ERXSTH 0x06 #define PI_DEFINE_ERXSTL 0x00 // Set PHLCON register #define PI_ERR_LED1_1 0b00111010 #define PI_ERR_LED0_1 0b10100111 // // Define Structure // // (1)Send Buffer struct PKT_SEND_def { unsigned char send_mac[6]; unsigned char system_mac[6]; unsigned char pkt_type[2]; unsigned char pkt_data[PI_SEND_MAX - 14]; }; union PKT_SEND_REC_def { struct PKT_SEND_def data; unsigned char record[PI_SEND_MAX]; } PKT_SEND_REC; // // (2)Recive Buffer struct PKT_RECIVE_def { unsigned char send_mac[6]; unsigned char system_mac[6]; unsigned char pkt_type[2]; unsigned char pkt_data[PI_SEND_MAX - 14]; }; union PKT_RECIVE_REC_def { struct PKT_RECIVE_def data; unsigned char record[PI_SEND_MAX]; } PKT_RECIVE_REC; // // Define function // void InitUART(void); void SendUART(unsigned char); void RecUART(unsigned char *); void SendUARTStr(unsigned char *); void InitADC(void); void Get_data(unsigned int *); void wait_1mS(unsigned int); void Timer(void); void PIC_PUT_PORT(unsigned char); char ENC28J60_INT_CHECK(void); char ENC28J60_SO_CHECK(void); void ENC28J60_SI_ON(void); void ENC28J60_SI_OFF(void); void ENC28J60_SCK_ON(void); void ENC28J60_SCK_OFF(void); void ENC28J60_CS_ON(void); void ENC28J60_CS_OFF(void); void ENC28J60_RESET_ON(void); void ENC28J60_RESET_OFF(void); void ENC28J60_INIT(void); void ENC28J60_SPI_SENDBYTE(unsigned char); void ENC28J60_SPI_RECBYTE( unsigned char *); void ENC28J60_SPI_READ_MAC(unsigned char, unsigned char *); void ENC28J60_SPI_READ_CR( unsigned char, unsigned char *); void ENC28J60_SPI_WRITE_CR(unsigned char, unsigned char ); void ENC28J60_SPI_WRITE_BM(unsigned char *,unsigned int); void ENC28J60_SPI_READ_BM( unsigned char *,unsigned int); void ENC28J60_SPI_SYSRESET(void); void ENC28J60_SELECT_BANK(unsigned char); void ENC28J60_READ_PHY(unsigned char, unsigned char *, unsigned char *); void ENC28J60_WRITE_PHY(unsigned char,unsigned char , unsigned char ); void ENC28J60_SEND(unsigned char *, unsigned int ); char ENC28J60_RECIVE(unsigned char *, unsigned int *); void ENC28J60_ERR_LED(unsigned char , unsigned char ); void Deb_dump(unsigned char); void WaitMNOP(unsigned int ); void WaitNOP(void); void prog01(void); char ENC28J60_CHECK_RECIVE(void); void Revive_main(void); void User_main(void); int main(void) { char status; // ******************* // 1.Initialize // ******************* // (1)Define Port // 1-1)All ports to digital ANSELA = 0x00000000; ANSELB = 0x00000000; // 1-2)Set the port TRISB = 0xFFFFF0FF; LATB = 0x00000000; PORTB = 0x00000000; // (2)Initialized ENC28J60 wait_1mS((unsigned int)500); ENC28J60_INIT(); // (3)Define UART // This function is used to debug the system // 2-1)Assign UART1 Pin (Rx1:RP13,Tx1:RP15) // U1RXR = 0b0011; // Rx:U1RX==>RPB13 // RPB15R = 0b0001; // Tx:RPB15R(PORTB15)==>U1TX // 2-2)Initialized UART // InitUART(); // ******************* // 2.Program Main // ******************* while(1){ // (1) Receiving process status = ENC28J60_CHECK_RECIVE(); if(status == PI_STATUS_PKT_SET){ Revive_main(); } // (2) Receiving process User_main(); } } //****************************************************************************************** // Function Name : Revive_main // Title : Receiving process // Input : // Output : //****************************************************************************************** void Revive_main(void) { unsigned int data_length; unsigned int lp; char status; // ******************* // 1.Initialize // ******************* for(lp=0;lp 400nS ENC28J60_RESET_ON(); wait_1mS((unsigned int)1); // > 50uS // (3)Software reset ENC28J60_SPI_SYSRESET(); wait_1mS((unsigned int)1); // (4)ECON1,ECON2 register // Clear TXRTS, RXEN // ECON1[3] TXRTS: Transmit Request to Send bit // ECON1[2] RXEN: Receive Enable bit // Caution !!!: // To prevent unexpected packets from arriving, it is recommended that RXEN be cleared before // altering the receive filter configuration (ERXFCON) and MAC address. ENC28J60_SPI_READ_CR( PI_REGADDR_ECON1,®_tmp); reg_tmp &= 0b11110000; ENC28J60_SPI_WRITE_CR(PI_REGADDR_ECON1, reg_tmp); // ******************* // 2.System setting // ******************* // -------------------------------- // (1)Initialized Receive Buffer // -------------------------------- // To program ERXRDPT, the host controller must write to ERXRDPTL first, followed by ERXRDPTH . !!!!! // 1-1)ERXST Pointer(ERXSTH:ERXSTL) Receive Buffer Start address (0000h + Transmit Buffer ==> 1fffh) ENC28J60_SELECT_BANK (PI_REGBANK_ERXSTL); ENC28J60_SPI_WRITE_CR(PI_REGADDR_ERXSTL, PI_DEFINE_ERXSTL); ENC28J60_SELECT_BANK (PI_REGBANK_ERXSTH); ENC28J60_SPI_WRITE_CR(PI_REGADDR_ERXSTH, PI_DEFINE_ERXSTH); //Max record 1514[byte] ==> 5EAh // 1-2)ERXND Pointer(ERXNDH:ERXNDL) Receive Buffer End address (end point 1fffh) ENC28J60_SELECT_BANK (PI_REGBANK_ERXNDL); ENC28J60_SPI_WRITE_CR(PI_REGADDR_ERXNDL, 0xff); ENC28J60_SELECT_BANK (PI_REGBANK_ERXNDH); ENC28J60_SPI_WRITE_CR(PI_REGADDR_ERXNDH, 0x1f); // 1-3)ERXRDPTL ENC28J60_SELECT_BANK (PI_REGBANK_ERXRDPTL); ENC28J60_SPI_WRITE_CR(PI_REGADDR_ERXRDPTL, PI_DEFINE_ERXSTL); // 1-4)ERXRDPTH ENC28J60_SELECT_BANK (PI_REGBANK_ERXRDPTH); ENC28J60_SPI_WRITE_CR(PI_REGADDR_ERXRDPTH, PI_DEFINE_ERXSTH); // 1-5)ERDPT ENC28J60_SELECT_BANK (PI_REGBANK_ERDPTL); ENC28J60_SPI_WRITE_CR(PI_REGADDR_ERDPTL, PI_DEFINE_ERXSTL); ENC28J60_SELECT_BANK (PI_REGBANK_ERDPTH); ENC28J60_SPI_WRITE_CR(PI_REGADDR_ERDPTH, PI_DEFINE_ERXSTH); // -------------------------------- // (2)Initialized Transmit Buffer // -------------------------------- // No explicit action is required to initialize the transmission buffer. !!!!!! // -------------------------------- // (3)Initialized Receive Filters // -------------------------------- // 3-1)ERXFCON // ERXFCON[7] UCEN: Unicast Filter Enable bit // When ANDOR = 1: // 1 = Packets not having a destination address matching the local MAC address will be discarded // 0 = Filter disabled // When ANDOR = 0: // 1 = Packets with a destination address matching the local MAC address will be accepted // 0 = Filter disabled // ERXFCON[6] ANDOR: AND/OR Filter Select bit // 1 = AND: Packets will be rejected unless all enabled filters accept the packet // 0 = OR: Packets will be accepted unless all enabled filters reject the packet // ERXFCON[5] CRCEN: Post-Filter CRC Check Enable bit // 1 = All packets with an invalid CRC will be discarded // 0 = The CRC validity will be ignored // ERXFCON[4] PMEN: Pattern Match Filter Enable bit // When ANDOR = 1: // 1 = Packets must meet the Pattern Match criteria or they will be discarded // 0 = Filter disabled // When ANDOR = 0: // 1 = Packets which meet the Pattern Match criteria will be accepted // 0 = Filter disabled // ERXFCON[3] MPEN: Magic Packet Filter Enable bit // When ANDOR = 1: // 1 = Packets must be Magic Packets for the local MAC address or they will be discarded // 0 = Filter disabled // When ANDOR = 0: // 1 = Magic Packets for the local MAC address will be accepted // 0 = Filter disabled // ERXFCON[2] HTEN: Hash Table Filter Enable bit // When ANDOR = 1: // 1 = Packets must meet the Hash Table criteria or they will be discarded // 0 = Filter disabled // When ANDOR = 0: // 1 = Packets which meet the Hash Table criteria will be accepted // 0 = Filter disabled // ERXFCON[1] MCEN: Multicast Filter Enable bit // When ANDOR = 1: // 1 = Packets must have the Least Significant bit set in the destination address or they will be discarded // 0 = Filter disabled // When ANDOR = 0: // 1 = Packets which have the Least Significant bit set in the destination address will be accepted // 0 = Filter disabled // ERXFCON[0] BCEN: Broadcast Filter Enable bit // When ANDOR = 1: // 1 = Packets must have a destination address of FF-FF-FF-FF-FF-FF or they will be discarded // 0 = Filter disabled // When ANDOR = 0: // 1 = Packets which have a destination address of FF-FF-FF-FF-FF-FF will be accepted // 0 = Filter disabled ENC28J60_SELECT_BANK (PI_REGBANK_ERXFCON); // ENC28J60_SPI_WRITE_CR(PI_REGADDR_ERXFCON, 0b11001111); // ENC28J60_SPI_WRITE_CR(PI_REGADDR_ERXFCON, 0b00000000); ENC28J60_SPI_WRITE_CR(PI_REGADDR_ERXFCON, 0b10000001); // -------------------------------- // (4)Waiting for OST // -------------------------------- // The ESTAT.CLKRDY bit should be polled to make certain that enough time has elapsed before proceeding // to modify the MAC and PHY registers. // // 4-1)ESTAT: ETHERNET STATUS REGISTER // ESTAT[7] INT: INT Interrupt Flag bit // 1 = INT interrupt is pending // 0 = No INT interrupt is pending // ESTAT[6] BUFER: Ethernet Buffer Error Status bit // 1 = An Ethernet read or write has generated a buffer error (overrun or underrun) // 0 = No buffer error has occurred // ESTAT[5] Reserved: Read as e0f // ESTAT[4] LATECOL: Late Collision Error bit // 1 = A collision occurred after 64 bytes had been transmitted // 0 = No collisions after 64 bytes have occurred // ESTAT[3] Unimplemented: Read as e0f // ESTAT[2] RXBUSY: Receive Busy bit // 1 = Receive logic is receiving a data packet // 0 = Receive logic is Idle // ESTAT[1] TXABRT: Transmit Abort Error bit // 1 = The transmit request was aborted // 0 = No transmit abort error // ESTAT[0] CLKRDY: Clock Ready bit(1) // 1 = OST has expired; PHY is ready // 0 = OST is still counting; PHY is not ready wait_1mS((unsigned int)1); ENC28J60_SELECT_BANK (PI_REGBANK_ESTAT); while(1){ ENC28J60_SPI_READ_CR (PI_REGADDR_ESTAT, ®_tmp); if((reg_tmp & 0b00000001) != 0)break; } // -------------------------------- // (5)MAC Initialization Settings // -------------------------------- // 5-1)MACON1: MAC CONTROL REGISTER 1 (Bank 2) // MACON1[7-5] Unimplemented: Read as e0f // MACON1[4] Reserved: Maintain as e0f // MACON1[3] TXPAUS: Pause Control Frame Transmission Enable bit // 1 = Allow the MAC to transmit pause control frames (needed for flow control in full duplex) // 0 = Disallow pause frame transmissions // MACON1[2] RXPAUS: Pause Control Frame Reception Enable bit // 1 = Inhibit transmissions when pause control frames are received (normal operation) // 0 = Ignore pause control frames which are received // MACON1[1] PASSALL: Pass All Received Frames Enable bit // 1 = Control frames received by the MAC will be written into the receive buffer if not filtered out // 0 = Control frames will be discarded after being processed by the MAC (normal operation) // MACON1[0] MARXEN: MAC Receive Enable bit // 1 = Enable packets to be received by the MAC // 0 = Disable packet reception ENC28J60_SELECT_BANK (PI_REGBANK_MACON1); ENC28J60_SPI_WRITE_CR(PI_REGADDR_MACON1, 0b00000001); // 5-2)MACON3: MAC CONTROL REGISTER 3 // MACON3[7-5] PADCFG<2:0>: Automatic Pad and CRC Configuration bits // 111 = All short frames will be zero-padded to 64 bytes and a valid CRC will then be appended // 110 = No automatic padding of short frames // 101 = MAC will automatically detect VLAN Protocol frames which have a 8100h type field and automatically pad to 64 bytes. // If the frame is not a VLAN frame, it will be padded to 60 bytes. // After padding, a valid CRC will be appended. // 100 = No automatic padding of short frames // 011 = All short frames will be zero-padded to 64 bytes and a valid CRC will then be appended // 010 = No automatic padding of short frames // 001 = All short frames will be zero-padded to 60 bytes and a valid CRC will then be appended // 000 = No automatic padding of short frames // MACON3[4] TXCRCEN: Transmit CRC Enable bit // 1 = MAC will append a valid CRC to all frames transmitted regardless of PADCFG bits. // TXCRCEN must be set if the PADCFG bits specify that a valid CRC will be appended. // 0 = MAC will not append a CRC. // The last 4 bytes will be checked and if it is an invalid CRC, it will be reported in the transmit status vector. // MACON3[3] PHDREN: Proprietary Header Enable bit // 1 = Frames presented to the MAC contain a 4-byte proprietary header which will not be used when calculating the CRC // 0 = No proprietary header is present. The CRC will cover all data (normal operation). // MACON3[2] HFRMEN: Huge Frame Enable bit // 1 = Frames of any size will be allowed to be transmitted and received // 0 = Frames bigger than MAMXFL will be aborted when transmitted or received // MACON3[1] FRMLNEN: Frame Length Checking Enable bit // 1 = The type/length field of transmitted and received frames will be checked. // If it represents a length, the frame size will be compared and mismatches will be reported in the transmit/receive status vector. // 0 = Frame lengths will not be compared with the type/length field // MACON3[0] FULDPX: MAC Full-Duplex Enable bit // 1 = MAC will operate in Full-Duplex mode. PDPXMD bit must also be set. // 0 = MAC will operate in Half-Duplex mode. PDPXMD bit must also be clear. ENC28J60_SELECT_BANK (PI_REGBANK_MACON3); ENC28J60_SPI_WRITE_CR(PI_REGADDR_MACON3, 0b11110000); // 5-3)MACON4: MAC CONTROL REGISTER 4 // MACON4[7] Unimplemented: Read as e0f // MACON4[6] DEFER: Defer Transmission Enable bit (applies to half duplex only) // 1 = When the medium is occupied, the MAC will wait indefinitely for it to become free when attempting // to transmit (use this setting for IEEE 802.3 compliance) // 0 = When the medium is occupied, the MAC will abort the transmission after the excessive deferral limit is reached // MACON4[5] BPEN: No Backoff During Backpressure Enable bit (applies to half duplex only) // 1 = After incidentally causing a collision during backpressure, the MAC will immediately begin retransmitting // 0 = After incidentally causing a collision during backpressure, the MAC will delay using the Binary // Exponential Backoff algorithm before attempting to retransmit (normal operation) // MACON4[4] NOBKOFF: No Backoff Enable bit (applies to half duplex only) // 1 = After any collision, the MAC will immediately begin retransmitting // 0 = After any collision, the MAC will delay using the Binary Exponential Backoff algorithm before attempting to retransmit (normal operation) // MACON4[3-2] Unimplemented: Read as e0f // MACON4[1-0] Reserved: Maintain as e0f ENC28J60_SELECT_BANK (PI_REGBANK_MACON4); ENC28J60_SPI_WRITE_CR(PI_REGADDR_MACON4, 0b01000000); //Set Half-Duplex mode // 5-4)MAMXFL: // Program the MAMXFL registers with the maximum frame length to be permitted to be received or transmitted. // Normal network nodes are designed to handle packets that are 1518 bytes or less. // 0d1518 => 0x05EE ENC28J60_SELECT_BANK (PI_REGBANK_MAMXFLL); ENC28J60_SPI_WRITE_CR(PI_REGADDR_MAMXFLL, 0xEE); ENC28J60_SELECT_BANK (PI_REGBANK_MAMXFLH); ENC28J60_SPI_WRITE_CR(PI_REGADDR_MAMXFLH, 0x05); // 5-5)MABBIPG: MAC BACK-TO-BACK INTER-PACKET GAP REGISTER // Most applications will program this register with 15h when Full-Duplex mode is used and 12h when Half-Duplex mode is used. // // MABBIPG[7] Unimplemented: Read as e0f // MABBIPG[6-0] BBIPG<6:0>: Back-to-Back Inter-Packet Gap Delay Time bits When FULDPX (MACON3<0>) = 1: // Nibble time offset delay between the end of one transmission and the beginning of the next in a back-to-back sequence. // The register value should be programmed to the desired period in nibble times minus 3. // The recommended setting is 15h which represents the minimum IEEE specified Inter-Packet Gap (IPG) of 9.6 s. // When FULDPX (MACON3<0>) = 0: // Nibble time offset delay between the end of one transmission and the beginning of the next in a back-to-back sequence. // The register value should be programmed to the desired period in nibble times minus 6. // The recommended setting is 12h which represents the minimum IEEE specified Inter-Packet Gap (IPG) of 9.6 s. ENC28J60_SELECT_BANK (PI_REGBANK_MABBIPG); ENC28J60_SPI_WRITE_CR(PI_REGADDR_MABBIPG, 0x12); // 5-6)MAIPGL // Most applications will program this register with 12h. ENC28J60_SELECT_BANK (PI_REGBANK_MAIPGL); ENC28J60_SPI_WRITE_CR(PI_REGADDR_MAIPGL, 0x12); // 5-7)MAIPGH // If half duplex is used, the Non-Back-to-Back Inter-Packet Gap register high byte, MAIPGH, should be programmed. // Most applications will program this register to 0Ch. ENC28J60_SELECT_BANK (PI_REGBANK_MAIPGH); ENC28J60_SPI_WRITE_CR(PI_REGADDR_MAIPGH, 0x0C); // 5-8)MACLCON1,MACLCON2 // Most applications will not need to change the default Reset values. // If the network is spread over exceptionally long cables, the default value of MACLCON2 may need to be increased. // 5-9)MAADR1:MAADR6 // Program the local MAC address into the MAADR1:MAADR6 registers. ENC28J60_SELECT_BANK (PI_REGBANK_MAADR1); ENC28J60_SPI_WRITE_CR(PI_REGADDR_MAADR1, PI_MAC_1); ENC28J60_SELECT_BANK (PI_REGBANK_MAADR2); ENC28J60_SPI_WRITE_CR(PI_REGADDR_MAADR2, PI_MAC_2); ENC28J60_SELECT_BANK (PI_REGBANK_MAADR3); ENC28J60_SPI_WRITE_CR(PI_REGADDR_MAADR3, PI_MAC_3); ENC28J60_SELECT_BANK (PI_REGBANK_MAADR4); ENC28J60_SPI_WRITE_CR(PI_REGADDR_MAADR4, PI_MAC_4); ENC28J60_SELECT_BANK (PI_REGBANK_MAADR5); ENC28J60_SPI_WRITE_CR(PI_REGADDR_MAADR5, PI_MAC_5); ENC28J60_SELECT_BANK (PI_REGBANK_MAADR6); ENC28J60_SPI_WRITE_CR(PI_REGADDR_MAADR6, PI_MAC_6); // -------------------------------- // (6)PHY Initialization Settings // -------------------------------- // 6-1)PHCON1 // // ENC28J60_READ_PHY( PI_PHYADDR_PHCON1, &data_h, &data_l); // data_h &= 0b11111110; // ENC28J60_WRITE_PHY(PI_PHYADDR_PHCON1, data_h, data_l); // 6-2)PHCON2: PHY CONTROL REGISTER 2 // PHCON2[15] Unimplemented: Read as e0f // PHCON2[14] FRCLNK: PHY Force Linkup bit // 1 = Force linkup even when no link partner is detected // 0 = Normal operation // PHCON2[13] TXDIS: Twisted-Pair Transmitter Disable bit // 1 = Disable twisted-pair transmitter // 0 = Normal operation // PHCON2[12-11] Reserved: Write as e0f // PHCON2[10] JABBER: Jabber Correction Disable bit // 1 = Disable jabber correction // 0 = Normal operation // PHCON2[9] Reserved: Write as e0f // PHCON2[8] HDLDIS: PHY Half-Duplex Loopback Disable bit // When PHCON1<8> = 1 or PHCON1<14> = 1: This bit is ignored. // When PHCON1<8> = 0 and PHCON1<14> = 0: // 1 = Transmitted data will only be sent out on the twisted-pair interface // 0 = Transmitted data will be looped back to the MAC and sent out on the twisted-pair interface // PHCON2[7-0] Reserved: Write as e0f ENC28J60_WRITE_PHY(PI_PHYADDR_PHCON2, 0x01, 0x00); // 6-3)PHCON3 // // 6-4)PHLCON: PHY MODULE LED CONTROL REGISTER // PHLCON[15-14] Reserved: Write as e0f // PHLCON[13-12] Reserved: Write as e1f // PHLCON[11-8] LACFG<3:0>: LEDA Configuration bits // 1111 = Reserved // 1110 = Display duplex status and collision activity (always stretched) // 1101 = Display link status and transmit/receive activity (always stretched) // 1100 = Display link status and receive activity (always stretched) // 1011 = Blink slow // 1010 = Blink fast // 1001 = Off // 1000 = On // 0111 = Display transmit and receive activity (stretchable) // 0110 = Reserved // 0101 = Display duplex status // 0100 = Display link status // 0011 = Display collision activity (stretchable) // 0010 = Display receive activity (stretchable) // 0001 = Display transmit activity (stretchable) // 0000 = Reserved // PHLCON[7-4] LBCFG<3:0>: LEDB Configuration bits // 1110 = Display duplex status and collision activity (always stretched) // 1101 = Display link status and transmit/receive activity (always stretched) // 1100 = Display link status and receive activity (always stretched) // 1011 = Blink slow // 1010 = Blink fast // 1001 = Off // 1000 = On // 0111 = Display transmit and receive activity (stretchable) // 0110 = Reserved // 0101 = Display duplex status // 0100 = Display link status // 0011 = Display collision activity (stretchable) // 0010 = Display receive activity (stretchable) // 0001 = Display transmit activity (stretchable) // 0000 = Reserved // PHLCON[3-2] LFRQ<1:0>: LED Pulse Stretch Time Configuration bits (see Table 2-1) // 11 = Reserved // 10 = Stretch LED events by TLSTRCH [ 40mS] // 01 = Stretch LED events by TMSTRCH [ 70mS] // 00 = Stretch LED events by TNSTRCH [140mS] // PHLCON[1] STRCH: LED Pulse Stretching Enable bit // 1 = Stretchable LED events will cause lengthened LED pulses based on LFRQ<1:0> configuration // 0 = Stretchable LED events will only be displayed while they are occurring // PHLCON[0] Reserved: Write as e0f ENC28J60_WRITE_PHY(PI_PHYADDR_PHLCON, 0b00110111, 0b01000010); // ******************* // 3.Start // ******************* // (1)ECON1,ECON2 register // Caution 1 !!!! // After setting RXEN, the Duplex mode and the Receive Buffer Start and End Pointers should not be modified // Caution 2 // ECON2[7] AUTOINC: Automatic Buffer Pointer Increment Enable bit // 1 = Automatically increment ERDPT or EWRPT on reading from or writing to EDATA // 0 = Do not automatically change ERDPT and EWRPT after the buffer is accessed // ECON2[6] PKTDEC: Packet Decrement bit(1) // 1 = Decrement the EPKTCNT register by one // 0 = Leave EPKTCNT unchanged // ECON1[2] RXEN: Receive Enable bit // 1 = Packets which pass the current filter configuration will be written into the receive buffer // 0 = All packets received will be ignored ENC28J60_SPI_WRITE_CR(PI_REGADDR_ECON2, 0b10000000); ENC28J60_SPI_WRITE_CR(PI_REGADDR_ECON1, 0b00000100); } //****************************************************************************************** // Function Name : ENC28J60_ERR_LED // Title : // Input : // Output : //****************************************************************************************** void ENC28J60_ERR_LED(unsigned char led_status1, unsigned char led_status0) { ENC28J60_WRITE_PHY(PI_PHYADDR_PHLCON, led_status1, led_status0); wait_1mS((unsigned int)2000); ENC28J60_INIT(); } //****************************************************************************************** // Function Name : ENC28J60_CHECK_RECIVE // Title : ENC28J60 Check reception // Input : // Output : //****************************************************************************************** char ENC28J60_CHECK_RECIVE(void) { unsigned char reg_tmp; // ********************** // 1.Check EIR: ETHERNET INTERRUPT REQUEST (FLAG) REGISTER // ********************** // EIR[7] Unimplemented: Read as e0f // EIR[6] PKTIF: Receive Packet Pending Interrupt Flag bit // 1 = Receive buffer contains one or more unprocessed packets; cleared when PKTDEC is set // 0 = Receive buffer is empty // EIR[5] DMAIF: DMA Interrupt Flag bit // 1 = DMA copy or checksum calculation has completed // 0 = No DMA interrupt is pending // EIR[4] LINKIF: Link Change Interrupt Flag bit // 1 = PHY reports that the link status has changed; read PHIR register to clear // 0 = Link status has not changed // EIR[3] TXIF: Transmit Interrupt Flag bit // 1 = Transmit request has ended // 0 = No transmit interrupt is pending // EIR[2] Reserved: Maintain as e0f // EIR[1] TXERIF: Transmit Error Interrupt Flag bit // 1 = A transmit error has occurred // 0 = No transmit error has occurred // EIR[0] RXERIF: Receive Error Interrupt Flag bit // 1 = A packet was aborted because there is insufficient buffer space or the packet count is 255 // 0 = No receive error interrupt is pending ENC28J60_SPI_READ_CR( PI_REGADDR_EIR,®_tmp); if((reg_tmp & 0b01000000) == 0){ return(PI_STATUS_PKT_EMPTY); }else{ return(PI_STATUS_PKT_SET); } } //****************************************************************************************** // Function Name : ENC28J60_RECIVE // Title : // Input : // Output : //****************************************************************************************** char ENC28J60_RECIVE(unsigned char w_data[], unsigned int *w_length) { unsigned char w_cntrol[6]; //[0]Next paket pointer L, [1]Next paket pointer H unsigned char tmp_ERDPTL; unsigned char tmp_ERDPTH; unsigned char tmp_ECON2; unsigned int lp; // ******************* // 1.Initialization // ******************* // (1)Read control record ENC28J60_SPI_READ_BM(&w_cntrol[0], (unsigned int)6); // (2)Read ERDPT register ENC28J60_SELECT_BANK (PI_REGBANK_ERDPTL); ENC28J60_SPI_READ_CR( PI_REGADDR_ERDPTL,&tmp_ERDPTL); ENC28J60_SELECT_BANK (PI_REGBANK_ERDPTH); ENC28J60_SPI_READ_CR( PI_REGADDR_ERDPTH,&tmp_ERDPTH); // (3)Calculate the length of the data if(tmp_ERDPTH > w_cntrol[1]){ // When the buffer wraps *w_length = ((unsigned int)w_cntrol[1] * (unsigned int)0x100 + (unsigned int)w_cntrol[0] ) + (unsigned int)0x1fff - ((unsigned int)tmp_ERDPTH * (unsigned int)0x100 + (unsigned int)tmp_ERDPTL ); }else{ *w_length = ((unsigned int)w_cntrol[1] * (unsigned int)0x100 + (unsigned int)w_cntrol[0] ) - ((unsigned int)tmp_ERDPTH * (unsigned int)0x100 + (unsigned int)tmp_ERDPTL ); } if(*w_length > (PI_SEND_MAX - 14 )) { ENC28J60_ERR_LED(PI_ERR_LED1_1, PI_ERR_LED0_1); // System error !!! return(PI_FAILURE); } // ******************* // 2.Read data // ******************* ENC28J60_SPI_READ_BM(&w_data[0], *w_length); *w_length = *w_length - 4; // Excluded from the data the CRC // ******************* // 3.Terminate // ******************* // (1)ECON2 register // Caution 1 !!!! // After setting RXEN, the Duplex mode and the Receive Buffer Start and End Pointers should not be modified // Caution 2 // ECON2[7] AUTOINC: Automatic Buffer Pointer Increment Enable bit // 1 = Automatically increment ERDPT or EWRPT on reading from or writing to EDATA // 0 = Do not automatically change ERDPT and EWRPT after the buffer is accessed // ECON2[6] PKTDEC: Packet Decrement bit(1) // 1 = Decrement the EPKTCNT register by one // 0 = Leave EPKTCNT unchanged ENC28J60_SPI_READ_CR( PI_REGADDR_ECON2,&tmp_ECON2); tmp_ECON2 |= 0b01000000; ENC28J60_SPI_WRITE_CR(PI_REGADDR_ECON2, tmp_ECON2); return(PI_NORMAL); } //****************************************************************************************** // Function Name : ENC28J60_SEND // Title : // Input : // Output : //****************************************************************************************** void ENC28J60_SEND(unsigned char w_data[], unsigned int w_length) { unsigned char w_tmp[2]; unsigned char tmp_ETXSTL; unsigned char tmp_ETXSTH; unsigned char tmp_ETXNDL; unsigned char tmp_ETXNDH; unsigned int tmp_length; unsigned char reg_tmp; // ******************* // 1.Initialization // ******************* // (1)Set ETXST address tmp_ETXSTL = 0x00; tmp_ETXSTH = 0x00; ENC28J60_SELECT_BANK (PI_REGBANK_ETXSTL); ENC28J60_SPI_WRITE_CR(PI_REGADDR_ETXSTL, tmp_ETXSTL); ENC28J60_SELECT_BANK (PI_REGBANK_ETXSTH); ENC28J60_SPI_WRITE_CR(PI_REGADDR_ETXSTH, tmp_ETXSTH); // (2)Set EWRPT address ENC28J60_SELECT_BANK (PI_REGBANK_EWRPTL); ENC28J60_SPI_WRITE_CR(PI_REGADDR_EWRPTL, 0x00); ENC28J60_SELECT_BANK (PI_REGBANK_EWRPTH); ENC28J60_SPI_WRITE_CR(PI_REGADDR_EWRPTH, 0x00); // (3)Set PER PACKET CONTROL BYTES // PPC BYTES[7-4] Unused // PPC BYTES[3] PHUGEEN: Per Packet Huge Frame Enable bit // When POVERRIDE = 1: // 1 = The packet will be transmitted in whole // 0 = The MAC will transmit up to the number of bytes specified by MAMXFL; // if the packet is larger than MAMXFL, it will be aborted after MAMXFL is reached // When POVERRIDE = 0: // This bit is ignored. // PPC BYTES[2] PPADEN: Per Packet Padding Enable bit // When POVERRIDE = 1: // 1 = The packet will be zero-padded to 60 bytes if it is less than 60 bytes // 0 = The packet will be transmitted without adding any padding bytes // When POVERRIDE = 0: This bit is ignored. // PPC BYTES[1] PCRCEN: Per Packet CRC Enable bit // When POVERRIDE = 1: // 1 = A valid CRC will be calculated and attached to the frame // 0 = No CRC will be appended; the last 4 bytes of the frame will be checked for validity as a CRC. // When POVERRIDE = 0: This bit is ignored. // PPC BYTES[0] POVERRIDE: Per Packet Override bit // 1 = The values of PCRCEN, PPADEN and PHUGEEN will override the configuration defined by MACON3 // 0 = The values in MACON3 will be used to determine how the packet will be transmitted w_tmp[0] = 0b00000111; ENC28J60_SPI_WRITE_BM(&w_tmp[0], (unsigned int)1); // (4)Set data ENC28J60_SPI_WRITE_BM(&w_data[0], w_length); // (5)Set ETXND address tmp_length = w_length + (unsigned int)(tmp_ETXSTH * 0x100) + (unsigned int)tmp_ETXSTH; tmp_ETXNDL = (unsigned char)(tmp_length % 0x100); tmp_ETXNDH = (unsigned char)(tmp_length / 0x100); ENC28J60_SELECT_BANK (PI_REGBANK_ETXNDL); ENC28J60_SPI_WRITE_CR(PI_REGADDR_ETXNDL, tmp_ETXNDL); ENC28J60_SELECT_BANK (PI_REGBANK_ETXNDH); ENC28J60_SPI_WRITE_CR(PI_REGADDR_ETXNDH, tmp_ETXNDH); // ******************* // 2.Send paket // ******************* // (1)Set ECON1.TXRTS ENC28J60_SPI_READ_CR( PI_REGADDR_ECON1,®_tmp); reg_tmp |= 0b00001000; ENC28J60_SPI_WRITE_CR(PI_REGADDR_ECON1, reg_tmp); // ******************* // 3.Terminate // ******************* // (1)Make sure the end of transmission while(1){ ENC28J60_SPI_READ_CR( PI_REGADDR_ECON1,®_tmp); if((reg_tmp & 0b00001000) == 0)break; //Check ECON1.TXRTS } } //****************************************************************************************** // Function Name : ENC28J60_WRITE_PHY // Title : Write PHY register // Input : // Output : // Caution : When a PHY register is written to, the entire 16 bits is written at once // selective bit writes are not implemented. // If it is necessary to reprogram only select bits in the register, the controller // must first read the PHY register, modify the resulting data and then write the // data back to the PHY register. //****************************************************************************************** void ENC28J60_WRITE_PHY(unsigned char phy_reg_address, unsigned char data_h, unsigned char data_l) { unsigned char reg_tmp; // ******************************** // 1.Write the address of the PHY register to write to into the MIREGADR register. // ******************************** ENC28J60_SELECT_BANK (PI_REGBANK_MIREGADR); ENC28J60_SPI_WRITE_CR(PI_REGADDR_MIREGADR, phy_reg_address); // ******************************** // 2.Write the lower 8 bits of data to write into the MIWRL register // ******************************** ENC28J60_SELECT_BANK (PI_REGBANK_MIWRL); ENC28J60_SPI_WRITE_CR(PI_REGADDR_MIWRL, data_l); // ******************************** // 3.Write the upper 8 bits of data to write into the MIWRH register. // Writing to this register automatically begins the MIIM transaction, so it must be written to after MIWRL. // The MISTAT.BUSY bit becomes set. // MISTAT[2]:NVALID, MISTAT[1]:SCAN, MISTAT[0]:BUSY // ******************************** ENC28J60_SELECT_BANK (PI_REGBANK_MIWRH); ENC28J60_SPI_WRITE_CR(PI_REGADDR_MIWRH, data_h); ENC28J60_SELECT_BANK (PI_REGBANK_MISTAT); while(1){ ENC28J60_SPI_READ_CR (PI_REGADDR_MISTAT, ®_tmp); if((reg_tmp & 0b00000001) == 0 )break; } } //****************************************************************************************** // Function Name : ENC28J60_READ_PHY // Title : Read PHY register // Input : // Output : //****************************************************************************************** void ENC28J60_READ_PHY(unsigned char phy_reg_address, unsigned char *data_h, unsigned char *data_l) { unsigned char reg_tmp; // ******************************** // 1.Write the address of the PHY register to read from into the MIREGADR register. // ******************************** ENC28J60_SELECT_BANK (PI_REGBANK_MIREGADR); ENC28J60_SPI_WRITE_CR(PI_REGADDR_MIREGADR, phy_reg_address); // ******************************** // 2.Set the MICMD.MIIRD. The read operation begins and the MISTAT.BUSY bit is set // MICMD[1]:MIISCAN, MICMD[0]:MIIRD // ******************************** ENC28J60_SELECT_BANK (PI_REGBANK_MICMD); ENC28J60_SPI_READ_CR (PI_REGADDR_MICMD, ®_tmp); reg_tmp |= 0b00000001; ENC28J60_SPI_WRITE_CR(PI_REGADDR_MICMD, reg_tmp); // ******************************** // 3.Wait 10.24 [uS] // Poll the MISTAT.BUSY bit to be certain that the operation is complete. // MISTAT[2]:NVALID, MISTAT[1]:SCAN, MISTAT[0]:BUSY // ******************************** WaitMNOP((unsigned int)1000); ENC28J60_SELECT_BANK (PI_REGBANK_MISTAT); while(1){ ENC28J60_SPI_READ_CR (PI_REGADDR_MISTAT, ®_tmp); if((reg_tmp & 0b00000001) == 0 )break; } // ******************************** // 4.Clear the MICMD.MIIRD bit. // MICMD[1]:MIISCAN, MICMD[0]:MIIRD // ******************************** ENC28J60_SELECT_BANK (PI_REGBANK_MICMD); ENC28J60_SPI_READ_CR (PI_REGADDR_MICMD, ®_tmp); reg_tmp &= 0b11111110; ENC28J60_SPI_WRITE_CR(PI_REGADDR_MICMD, reg_tmp); // ******************************** // 5.Read the desired data from the MIRDL and MIRDH registers. // The order that these bytes are accessed is unimportant. // ******************************** ENC28J60_SELECT_BANK (PI_REGBANK_MIRDL); ENC28J60_SPI_READ_CR (PI_REGADDR_MIRDL, data_l); ENC28J60_SELECT_BANK (PI_REGBANK_MIRDH); ENC28J60_SPI_READ_CR (PI_REGADDR_MIRDH, data_h); } //****************************************************************************************** // Function Name : ENC28J60_SELECT_BANK // Title : Select memory bank // Input : // Output : //****************************************************************************************** void ENC28J60_SELECT_BANK(unsigned char bank_no) { unsigned char reg_tmp; // ******************************************* // 1. ECON1: ETHERNET CONTROL REGISTER 1 // ECON1[7] TXRST: Transmit Logic Reset bit // 1 = Transmit logic is held in Reset // 0 = Normal operation // ECON1[6] RXRST: Receive Logic Reset bit // 1 = Receive logic is held in Reset // 0 = Normal operations // ECON1[5] DMAST: DMA Start and Busy Status bit // 1 = DMA copy or checksum operation is in progress // 0 = DMA hardware is Idle // ECON1[4] CSUMEN: DMA Checksum Enable bit // 1 = DMA hardware calculates checksums // 0 = DMA hardware copies buffer memory // ECON1[3] TXRTS: Transmit Request to Send bit // 1 = The transmit logic is attempting to transmit a packet // 0 = The transmit logic is Idle // ECON1[2] RXEN: Receive Enable bit // 1 = Packets which pass the current filter configuration will be written into the receive buffer // 0 = All packets received will be ignored // ECON1[1-0] BSEL<1:0>: Bank Select bits // 11 = SPI accesses registers in Bank 3 // 10 = SPI accesses registers in Bank 2 // 01 = SPI accesses registers in Bank 1 // 00 = SPI accesses registers in Bank 0 // ******************************************* // (1)Read ECON1 register ENC28J60_SPI_READ_CR(PI_REGADDR_ECON1, ®_tmp); // (2)Update ECON1 register reg_tmp &= 0b11111100; switch(bank_no){ case PI_BANK0: reg_tmp |= 0b00000000; break; case PI_BANK1: reg_tmp |= 0b00000001; break; case PI_BANK2: reg_tmp |= 0b00000010; break; case PI_BANK3: reg_tmp |= 0b00000011; break; default: return; } ENC28J60_SPI_WRITE_CR(PI_REGADDR_ECON1, reg_tmp); } //****************************************************************************************** // Function Name : ENC28J60_SPI_SYSRESET * // Title : System reset // Input : // Output : //****************************************************************************************** void ENC28J60_SPI_SYSRESET(void) { // ******************* // 1.Initialize // ******************* // (1)The default value ENC28J60_SCK_OFF(); ENC28J60_CS_ON(); // ******************* // 2.System reset command // ******************* // (1)Start WaitMNOP((unsigned int)100); ENC28J60_CS_OFF(); WaitMNOP((unsigned int)10); // (2)Issue the reset command ENC28J60_SPI_SENDBYTE((unsigned char)PI_ENC28CMD_SRC); // ******************* // 3.Terminate // ******************* // (1)Terminate WaitNOP(); ENC28J60_SCK_OFF(); WaitNOP(); ENC28J60_SI_OFF(); WaitMNOP((unsigned int)10); ENC28J60_CS_ON(); WaitMNOP((unsigned int)10); } //****************************************************************************************** // Function Name : ENC28J60_SPI_READ_BM * // Title : Read buffer memory // Input : // Output : // Caution 1 : This function set the automatic incriment function beforehand. !!! //****************************************************************************************** void ENC28J60_SPI_READ_BM(unsigned char r_data[], unsigned int r_length) { unsigned char command_format; unsigned int lp; // ******************* // 1.Initialize // ******************* // (1)The default value ENC28J60_SCK_OFF(); ENC28J60_CS_ON(); // ******************* // 2.READ CR register // ******************* // (1)Start WaitMNOP((unsigned int)10); ENC28J60_CS_OFF(); WaitMNOP((unsigned int)10); // (2)Issue the read command command_format = PI_ENC28CMD_RBM; ENC28J60_SPI_SENDBYTE(command_format); WaitNOP(); ENC28J60_SI_OFF(); WaitNOP(); // (3)Read data for(lp=0;lp 50nS // (2)Issue the write command command_format = PI_ENC28CMD_WBM; ENC28J60_SPI_SENDBYTE(command_format); // (3)Write data for(lp=0;lp 210nS ENC28J60_CS_ON(); WaitMNOP((unsigned int)10); // > 50nS } //****************************************************************************************** // Function Name : ENC28J60_SPI_WRITE_CR * // Title : Write CR register // Input : // Output : //****************************************************************************************** void ENC28J60_SPI_WRITE_CR(unsigned char in_address, unsigned char w_data) { unsigned char command_format; // ******************* // 1.Initialize // ******************* // (1)The default value ENC28J60_SCK_OFF(); ENC28J60_CS_ON(); // ******************* // 2.Write CR register // ******************* // (1)Start WaitMNOP((unsigned int)10); ENC28J60_CS_OFF(); WaitMNOP((unsigned int)10); // > 50nS // (2)Issue the write command in_address &= 0b00011111; command_format = PI_ENC28CMD_WCR | in_address; ENC28J60_SPI_SENDBYTE(command_format); // (3)Write data ENC28J60_SPI_SENDBYTE(w_data); // ******************* // 3.Terminate // ******************* // (1)Terminate WaitNOP(); ENC28J60_SCK_OFF(); WaitNOP(); ENC28J60_SI_OFF(); WaitMNOP((unsigned int)10); // > 210nS ENC28J60_CS_ON(); WaitMNOP((unsigned int)10); // > 50nS } //****************************************************************************************** // Function Name : ENC28J60_SPI_READ_MAC // Title : READ MAC register // Input : // Output : //****************************************************************************************** void ENC28J60_SPI_READ_MAC(unsigned char in_address, unsigned char *r_data) { unsigned char command_format; unsigned char dummy_data; // ******************* // 1.Initialize // ******************* // (1)The default value ENC28J60_SCK_OFF(); ENC28J60_CS_ON(); // ******************* // 2.READ MAC register // ******************* // (1)Start WaitMNOP((unsigned int)10); ENC28J60_CS_OFF(); WaitMNOP((unsigned int)10); // (2)Issue the read command in_address &= 0b00011111; command_format = PI_ENC28CMD_RCR | in_address; ENC28J60_SPI_SENDBYTE(command_format); WaitNOP(); ENC28J60_SI_OFF(); WaitNOP(); // (3)Read data ENC28J60_SPI_RECBYTE(&dummy_data); ENC28J60_SPI_RECBYTE(r_data); // ******************* // 3.Terminate // ******************* // (1)Dummy Clock WaitNOP(); ENC28J60_SCK_ON(); WaitNOP(); ENC28J60_SCK_OFF(); WaitNOP(); // (2)Terminate ENC28J60_CS_ON(); } //****************************************************************************************** // Function Name : ENC28J60_SPI_READ_CR // Title : READ CR register // Input : // Output : //****************************************************************************************** void ENC28J60_SPI_READ_CR(unsigned char in_address, unsigned char *r_data) { unsigned char command_format; // ******************* // 1.Initialize // ******************* // (1)The default value ENC28J60_SCK_OFF(); ENC28J60_CS_ON(); // ******************* // 2.READ CR register // ******************* // (1)Start WaitMNOP((unsigned int)10); ENC28J60_CS_OFF(); WaitMNOP((unsigned int)10); // (2)Issue the read command in_address &= 0b00011111; command_format = PI_ENC28CMD_RCR | in_address; ENC28J60_SPI_SENDBYTE(command_format); WaitNOP(); ENC28J60_SI_OFF(); WaitNOP(); // (3)Read data ENC28J60_SPI_RECBYTE(r_data); // ******************* // 3.Terminate // ******************* // (1)Dummy Clock WaitNOP(); ENC28J60_SCK_ON(); WaitNOP(); ENC28J60_SCK_OFF(); WaitNOP(); // (2)Terminate ENC28J60_CS_ON(); } //****************************************************************************************** // Function Name : ENC28J60_SPI_RECBYTE // Title : ENC28J60 SPI RECIVE BYTE // Input : // Output : // Termination status : Clock signal Low level !!! // Data are read on the falling edge of stand !!!!! //****************************************************************************************** void ENC28J60_SPI_RECBYTE(unsigned char *out_c) { unsigned int lp; *out_c = 0x00; for(lp=0;lp<8;lp++){ *out_c = *out_c << 1; WaitNOP(); ENC28J60_SCK_ON(); WaitNOP(); ENC28J60_SCK_OFF(); WaitNOP(); if(ENC28J60_SO_CHECK() == PI_STATUS_H){ *out_c = *out_c + 0x01; }else{ *out_c = *out_c + 0x00; // Infomation: There is no need to do anything. } } } //****************************************************************************************** // Function Name : ENC28J60_SPI_SENDBYTE // Title : ENC28J60 SPI SEND BYTE // Input : // Output : // Termination status : Clock signal Higth level !!!! // Writes data at the rising edge !!!! //****************************************************************************************** void ENC28J60_SPI_SENDBYTE(unsigned char in_c) { unsigned int lp; for(lp=0;lp<8;lp++){ if((in_c & 0b10000000) == 0){ WaitNOP(); ENC28J60_SCK_OFF(); WaitNOP(); ENC28J60_SI_OFF(); WaitNOP(); ENC28J60_SCK_ON(); WaitNOP(); }else{ WaitNOP(); ENC28J60_SCK_OFF(); WaitNOP(); ENC28J60_SI_ON(); WaitNOP(); ENC28J60_SCK_ON(); WaitNOP(); } in_c = in_c << 1; } } //****************************************************************************************** // Function Name : ENC28J60_INT_CHECK (RB14) // Title : // Input : // Output : //****************************************************************************************** char ENC28J60_INT_CHECK(void) { if((PORTB & 0x00004000)== 0x00000000)return(PI_STATUS_L); return(PI_STATUS_H); } //****************************************************************************************** // Function Name : ENC28J60_SO_CHECK (RB12) // Title : // Input : // Output : //****************************************************************************************** char ENC28J60_SO_CHECK(void) { if((PORTB & 0x00001000)== 0x00000000)return(PI_STATUS_L); return(PI_STATUS_H); } //****************************************************************************************** // Function Name : ENC28J60_SI_ON (RB11) // Title : // Input : // Output : //****************************************************************************************** void ENC28J60_SI_ON(void) { PORTB |= 0x00000800; } //****************************************************************************************** // Function Name : ENC28J60_SI_OFF (RB11) // Title : // Input : // Output : //****************************************************************************************** void ENC28J60_SI_OFF(void) { PORTB &= 0xFFFFF7FF; } //****************************************************************************************** // Function Name : ENC28J60_SCK_ON (RB10) // Title : // Input : // Output : //****************************************************************************************** void ENC28J60_SCK_ON(void) { PORTB |= 0x00000400; } //****************************************************************************************** // Function Name : ENC28J60_SCK_OFF (RB10) // Title : // Input : // Output : //****************************************************************************************** void ENC28J60_SCK_OFF(void) { PORTB &= 0xFFFFFBFF; } //****************************************************************************************** // Function Name : ENC28J60_CS_ON (RB9) // Title : // Input : // Output : //****************************************************************************************** void ENC28J60_CS_ON(void) { PORTB |= 0x00000200; } //****************************************************************************************** // Function Name : ENC28J60_CS_OFF (RB9) // Title : // Input : // Output : //****************************************************************************************** void ENC28J60_CS_OFF(void) { PORTB &= 0xFFFFFDFF; } //****************************************************************************************** // Function Name : ENC28J60_RESET_ON (RB8) // Title : // Input : // Output : //****************************************************************************************** void ENC28J60_RESET_ON(void) { PORTB |= 0x00000100; } //****************************************************************************************** // Function Name : ENC28J60_RESET_OFF (RB8) // Title : // Input : // Output : //****************************************************************************************** void ENC28J60_RESET_OFF(void) { PORTB &= 0xFFFFFEFF; } //****************************************************************************************** // Function Name : PIC_PUT_PORT // Title : // Input : // Output : //****************************************************************************************** void PIC_PUT_PORT(unsigned char put_data) { TRISB &= 0xFFFFFF00; // PORTB = PORTB | (unsigned int)put_data; PORTB = PORTB & ( 0xFFFFFF00 | (unsigned int)put_data); } //****************************************************************************************** // Function Name : InitADC // Title : Initialized A/D Converter // Input : // Output : //****************************************************************************************** void InitADC(void) { // ******************************* // 0.Set ANSEL bits // ******************************* ANSELAbits.ANSA0 = 1; //AN0: Analog PORT // ******************************* // 1.AD1CON1: ADC CONTROL REGISTER 1 // AD1CON1[31-16] Unimplemented: Read as e0f // AD1CON1[15] ON: ADC Operating Mode bit(1) // 1 = ADC module is operating // 0 = ADC module is not operating // AD1CON1[14] Unimplemented: Read as e0f // AD1CON1[13] SIDL: Stop in Idle Mode bit // 1 = Discontinue module operation when device enters Idle mode // 0 = Continue module operation in Idle mode // AD1CON1[12-11] Unimplemented: Read as e0f // AD1CON1[10-8] FORM<2:0>: Data Output Format bits // 011 = Signed Fractional 16-bit (DOUT = 0000 0000 0000 0000 sddd dddd dd00 0000) // 010 = Fractional 16-bit (DOUT = 0000 0000 0000 0000 dddd dddd dd00 0000) // 001 = Signed Integer 16-bit (DOUT = 0000 0000 0000 0000 ssss sssd dddd dddd) // 000 = Integer 16-bit (DOUT = 0000 0000 0000 0000 0000 00dd dddd dddd) // 111 = Signed Fractional 32-bit (DOUT = sddd dddd dd00 0000 0000 0000 0000) // 110 = Fractional 32-bit (DOUT = dddd dddd dd00 0000 0000 0000 0000 0000) // 101 = Signed Integer 32-bit (DOUT = ssss ssss ssss ssss ssss sssd dddd dddd) // 100 = Integer 32-bit (DOUT = 0000 0000 0000 0000 0000 00dd dddd dddd) // AD1CON1[7-5] SSRC<2:0>: Conversion Trigger Source Select bits // 111 = Internal counter ends sampling and starts conversion (auto convert) // 110 = Reserved // 101 = Reserved // 100 = Reserved // 011 = CTMU ends sampling and starts conversion // 010 = Timer 3 period match ends sampling and starts conversion // 001 = Active transition on INT0 pin ends sampling and starts conversion // 000 = Clearing SAMP bit ends sampling and starts conversion // AD1CON1[4] CLRASAM: Stop Conversion Sequence bit (when the first ADC interrupt is generated) // 1 = Stop conversions when the first ADC interrupt is generated. Hardware clears the ASAM bit when the // ADC interrupt is generated. // 0 = Normal operation, buffer contents will be overwritten by the next conversion sequence // AD1CON1[3] Unimplemented: Read as e0f // AD1CON1[2] ASAM: ADC Sample Auto-Start bit // 1 = Sampling begins immediately after last conversion completes; SAMP bit is automatically set. // 0 = Sampling begins when SAMP bit is set // AD1CON1[1] SAMP: ADC Sample Enable bit(2) // 1 = The ADC sample and hold amplifier is sampling // 0 = The ADC sample/hold amplifier is holding // When ASAM = 0, writing e1f to this bit starts sampling. // When SSRC = 000, writing e0f to this bit will end sampling and start conversion. // AD1CON1[0] DONE: Analog-to-Digital Conversion Status bit(3) // 1 = Analog-to-digital conversion is done // 0 = Analog-to-digital conversion is not done or has not started // Clearing this bit will not affect any operation in progress. // ******************************* AD1CON1bits.ON = 1; AD1CON1bits.SIDL = 0; AD1CON1bits.FORM = 0b000; AD1CON1bits.SSRC = 0b111; AD1CON1bits.CLRASAM = 0; AD1CON1bits.ASAM = 0; AD1CON1bits.SAMP = 0; AD1CON1bits.DONE = 0; // ******************************* // 2.AD1CON2: ADC CONTROL REGISTER 2 // AD1CON2[31-16] Unimplemented: Read as e0f // AD1CON2[15-13] VCFG<2:0>: Voltage Reference Configuration bits // VREFH VREFL // 000 AVDD AVss // 001 External VREF+ pin AVSS // 010 AVDD External VREF- pin // 011 External VREF+ pin External VREF- pin // 1xx AVDD AVSS // AD1CON2[12] OFFCAL: Input Offset Calibration Mode Select bit // 1 = Enable Offset Calibration mode // Positive and negative inputs of the sample and hold amplifier are connected to VREFL // 0 = Disable Offset Calibration mode // The inputs to the sample and hold amplifier are controlled by AD1CHS or AD1CSSL // AD1CON2[11] Unimplemented: Read as e0f // AD1CON2[10] CSCNA: Input Scan Select bit // 1 = Scan inputs // 0 = Do not scan inputs // AD1CON2[9-8] Unimplemented: Read as e0f // AD1CON2[7] BUFS: Buffer Fill Status bit // Only valid when BUFM = 1. // 1 = ADC is currently filling buffer 0x8-0xF, user should access data in 0x0-0x7 // 0 = ADC is currently filling buffer 0x0-0x7, user should access data in 0x8-0xF // AD1CON2[6] Unimplemented: Read as e0f // AD1CON2[5-2] SMPI<3:0>: Sample/Convert Sequences Per Interrupt Selection bits // 1111 = Interrupts at the completion of conversion for each 16th sample/convert sequence // 1110 = Interrupts at the completion of conversion for each 15th sample/convert sequence // **** // 0001 = Interrupts at the completion of conversion for each 2nd sample/convert sequence // 0000 = Interrupts at the completion of conversion for each sample/convert sequence // AD1CON2[1] BUFM: ADC Result Buffer Mode Select bit // 1 = Buffer configured as two 8-word buffers, ADC1BUF7-ADC1BUF0, ADC1BUFF-ADCBUF8 // 0 = Buffer configured as one 16-word buffer ADC1BUFF-ADC1BUF0 // AD1CON2[0] ALTS: Alternate Input Sample Mode Select bit // 1 = Uses Sample A input multiplexer settings for first sample, then alternates between Sample B and // Sample A input multiplexer settings for all subsequent samples // 0 = Always use Sample A input multiplexer settings // ******************************* AD1CON2bits.VCFG = 0b000; AD1CON2bits.OFFCAL = 0; AD1CON2bits.CSCNA = 0; AD1CON2bits.BUFS = 0; AD1CON2bits.SMPI = 0b0000; AD1CON2bits.BUFM = 0; AD1CON2bits.ALTS = 0; // ******************************* // 3.AD1CON3: ADC CONTROL REGISTER 3 // AD1CON3[31-16] Unimplemented: Read as e0f // AD1CON3[15] ADRC: ADC Conversion Clock Source bit // 1 = Clock derived from FRC // 0 = Clock derived from Peripheral Bus Clock (PBCLK) // AD1CON3[14-13] Unimplemented: Read as e0f // AD1CON3[12-8] SAMC<4:0>: Auto-Sample Time bits(1) // 11111 = 31 TAD // * // * // * // 00001 =1 TAD // 00000 =0 TAD (Not allowed) // AD1CON3[7-0] ADCS<7:0>: ADC Conversion Clock Select bits(2) //@@@@@11111111 =TPBEE2E(ADCS<7:0> + 1) = 512ETPB = TAD // * // * // * // 00000001 =TPBE2E(ADCS<7:0> + 1) = 4ETPB = TAD // 00000000 =TPBE2E(ADCS<7:0> + 1) = 2ETPB = TAD // ******************************* AD1CON3bits.ADRC = 1; AD1CON3bits.SAMC = 0b11111; AD1CON3bits.ADCS = 0b11111111; // ******************************* // 4.AD1CHS: ADC INPUT SELECT REGISTER // AD1CHS[31] CH0NB: Negative Input Select bit for Sample B // 1 = Channel 0 negative input is AN1 // 0 = Channel 0 negative input is VREFL // AD1CHS[30-28] Unimplemented: Read as e0f // AD1CHS[27-24] CH0SB<3:0>: Positive Input Select bits for Sample B // 1111 = Channel 0 positive input is Open(1) // 1110 = Channel 0 positive input is IVREF(2) // 1101 = Channel 0 positive input is CTMU temperature sensor (CTMUT)(3) // 1100 = Channel 0 positive input is AN12(4) // E // E // E // 0001 = Channel 0 positive input is AN1 // 0000 = Channel 0 positive input is AN0 // AD1CHS[23] CH0NA: Negative Input Select bit for Sample A Multiplexer Setting(2) // 1 = Channel 0 negative input is AN1 // 0 = Channel 0 negative input is VREFL // AD1CHS[22-20] Unimplemented: Read as e0f // AD1CHS[19-16] CH0SA<3:0>: Positive Input Select bits for Sample A Multiplexer Setting // 1111 = Channel 0 positive input is Open(1) // 1110 = Channel 0 positive input is IVREF(2) // 1101 = Channel 0 positive input is CTMU temperature (CTMUT)(3) // 1100 = Channel 0 positive input is AN12(4) // E // E // E // 0001 = Channel 0 positive input is AN1 // 0000 = Channel 0 positive input is AN0 // AD1CHS[15-0] Unimplemented: Read as e0f // ******************************* AD1CHSbits.CH0NB = 0; AD1CHSbits.CH0SB = 0b0000; AD1CHSbits.CH0NA = 0; AD1CHSbits.CH0SA = 0b0000; // ******************************* // 5.AD1CSSL: ADC INPUT SCAN SELECT REGISTER // AD1CSSL[31-16] Unimplemented: Read as e0f // AD1CSSL[15-0] CSSL<15:0>: ADC Input Pin Scan Selection bits(1,2) // 1 = Select ANx for input scan // 0 = Skip ANx for input scan // Note 1: CSSL = ANx, where x = 0-12; CSSL13 selects CTMU input for scan; CSSL14 selects IVREF for scan; // CSSL15 selects VSS for scan. // 2: On devices with less than 13 analog inputs, all CSSLx bits can be selected; however, inputs selected for // scan without a corresponding input on the device will convert to VREFL. // ******************************* AD1CSSLbits.CSSL0 = 0; AD1CSSLbits.CSSL1 = 0; AD1CSSLbits.CSSL2 = 0; AD1CSSLbits.CSSL3 = 0; AD1CSSLbits.CSSL4 = 0; AD1CSSLbits.CSSL5 = 0; AD1CSSLbits.CSSL6 = 0; AD1CSSLbits.CSSL7 = 0; AD1CSSLbits.CSSL8 = 0; AD1CSSLbits.CSSL9 = 0; AD1CSSLbits.CSSL10 = 0; AD1CSSLbits.CSSL11 = 0; AD1CSSLbits.CSSL12 = 0; AD1CSSLbits.CSSL13 = 0; AD1CSSLbits.CSSL14 = 0; AD1CSSLbits.CSSL15 = 0; } //****************************************************************************************** // Function Name : Get_data // Title : Get A/D-Converter-Data // Input : // Output : //****************************************************************************************** void Get_data(unsigned int *adc_data) { AD1CON1bits.SAMP=1; while(!IFS0bits.AD1IF); *adc_data = (unsigned int)ADC1BUF0; } //****************************************************************************************** // Function Name : cnv_data // Title : Convert data format // Input : // Output : //****************************************************************************************** void cnv_data(unsigned char out_data[], unsigned int in_data) { in_data = in_data * 3300 / 1023 ; sprintf(out_data,"%8d",in_data); strcat(out_data, "[mV] "); } //**************************************************************************** // Function Name : Deb_dump // Title : Debug UART dump // Input : // Output : // Description : This function is used to debug the system //**************************************************************************** void Deb_dump(unsigned char in_char) { unsigned char in_char_h,in_char_l; unsigned char dmp_char_h,dmp_char_l; in_char_h = ( in_char >> 4 ) & 0b00001111; in_char_l = in_char & 0b00001111; switch(in_char_h){ case 0x0a : dmp_char_h = 'a'; break; case 0x0b : dmp_char_h = 'b'; break; case 0x0c : dmp_char_h = 'c'; break; case 0x0d : dmp_char_h = 'd'; break; case 0x0e : dmp_char_h = 'e'; break; case 0x0f : dmp_char_h = 'f'; break; default: dmp_char_h = in_char_h | 0x30 ; } switch(in_char_l){ case 0x0a : dmp_char_l = 'a'; break; case 0x0b : dmp_char_l = 'b'; break; case 0x0c : dmp_char_l = 'c'; break; case 0x0d : dmp_char_l = 'd'; break; case 0x0e : dmp_char_l = 'e'; break; case 0x0f : dmp_char_l = 'f'; break; default: dmp_char_l = in_char_l | 0x30 ; } SendUART('['); SendUART(dmp_char_h ); SendUART(dmp_char_l ); SendUART(']'); } //****************************************************************************************** // Function Name : InitUART // Title : Initialized UART // Input : // Output : //****************************************************************************************** void InitUART(void) { // ************************** // (1)Define UxMODE: UARTx MODE REGISTER // UxMODE[31-16] Unimplemented: Read as e0f // UxMODE[15] ON: UARTx Enable bit(1) // 1 = UARTx is enabled. UARTx pins are controlled by UARTx as defined by UEN<1:0> and UTXEN control bits // 0 = UARTx is disabled. All UARTx pins are controlled by corresponding bits in the PORTx, TRISx and LATx // registers; UARTx power consumption is minimal // UxMODE[14] Unimplemented: Read as e0f // UxMODE[13] SIDL: Stop in Idle Mode bit // 1 = Discontinue operation when device enters Idle mode // 0 = Continue operation in Idle mode // UxMODE[12] IREN: IrDA Encoder and Decoder Enable bit // 1 = IrDA is enabled // 0 = IrDA is disabled // UxMODE[11] RTSMD: Mode Selection for UxRTS Pin bit // 1 = UxRTS pin is in Simplex mode // 0 = UxRTS pin is in Flow Control mode // UxMODE[10] Unimplemented: Read as e0f // UxMODE[9-8] UEN<1:0>: UARTx Enable bits // 11 = UxTX, UxRX and UxBCLK pins are enabled and used; UxCTS pin is controlled by corresponding bits // in the PORTx register // 10 = UxTX, UxRX, UxCTS and UxRTS pins are enabled and used // 01 = UxTX, UxRX and UxRTS pins are enabled and used; UxCTS pin is controlled by corresponding bits // in the PORTx register // 00 = UxTX and UxRX pins are enabled and used; UxCTS and UxRTS/UxBCLK pins are controlled by // corresponding bits in the PORTx register // UxMODE[7] WAKE: Enable Wake-up on Start bit Detect During Sleep Mode bit // 1 = Wake-up enabled // 0 = Wake-up disabled // UxMODE[6] LPBACK: UARTx Loopback Mode Select bit // 1 = Loopback mode is enabled // 0 = Loopback mode is disabled // UxMODE[5] ABAUD: Auto-Baud Enable bit // 1 = Enable baud rate measurement on the next character - requires reception of Sync character (0x55); // cleared by hardware upon completion // 0 = Baud rate measurement disabled or completed // UxMODE[4] RXINV: Receive Polarity Inversion bit // 1 = UxRX Idle state is e0f // 0 = UxRX Idle state is e1f // UxMODE[3] BRGH: High Baud Rate Enable bit // 1 = High-Speed mode - 4x baud clock enabled // 0 = Standard Speed mode - 16x baud clock enabled // UxMODE[2-1] PDSEL<1:0>: Parity and Data Selection bits // 11 = 9-bit data, no parity // 10 = 8-bit data, odd parity // 01 = 8-bit data, even parity // 00 = 8-bit data, no parity // UxMODE[0] STSEL: Stop Selection bit // 1 = 2 Stop bits // 0 = 1 Stop bit // ************************** // U1MODEbits.ON = 1; U1MODEbits.ON = 0; U1MODEbits.SIDL = 0; U1MODEbits.IREN = 0; U1MODEbits.RTSMD = 0; U1MODEbits.UEN0 = 0; U1MODEbits.UEN1 = 0; U1MODEbits.WAKE = 0; U1MODEbits.LPBACK = 0; U1MODEbits.ABAUD = 0; U1MODEbits.RXINV = 0; U1MODEbits.BRGH = 0; U1MODEbits.PDSEL1 = 0; U1MODEbits.PDSEL0 = 0; U1MODEbits.STSEL = 0; // ************************** // (2)Define U1BRG // BAUDRATE(Register)=SYSCLK/16/BAUDRATE-1 // ************************** U1BRG = 259; // BAUDRATE = 40MHz/16/9600-1 = 0d259 9600BPS(40MHz) // ************************** // (3)Define UxSTA: UARTx STATUS AND CONTROL REGISTER // UxSTA[31-25] Unimplemented: Read as e0f // UxSTA[24] ADM_EN: Automatic Address Detect Mode Enable bit // 1 = Automatic Address Detect mode is enabled // 0 = Automatic Address Detect mode is disabled // UxSTA[23-16] ADDR<7:0>: Automatic Address Mask bits // When the ADM_EN bit is e1f, this value defines the address character to use for automatic address detection. // UxSTA[15-14] UTXISEL<1:0>: TX Interrupt Mode Selection bits // 11 = Reserved, do not use // 10 = Interrupt is generated and asserted while the transmit buffer is empty // 01 = Interrupt is generated and asserted when all characters have been transmitted // 00 = Interrupt is generated and asserted while the transmit buffer contains at least one empty space // UxSTA[13] UTXINV: Transmit Polarity Inversion bit // If IrDA mode is disabled (i.e., IREN (UxMODE<12>) is e0f): // 1 = UxTX Idle state is e0f // 0 = UxTX Idle state is e1f // If IrDA mode is enabled (i.e., IREN (UxMODE<12>) is e1f): // 1 = IrDA encoded UxTX Idle state is e1f // 0 = IrDA encoded UxTX Idle state is e0f // UxSTA[12] URXEN: Receiver Enable bit // 1 = UARTx receiver is enabled. UxRX pin is controlled by UARTx (if ON = 1) // 0 = UARTx receiver is disabled. UxRX pin is ignored by the UARTx module. UxRX pin is controlled by port. // UxSTA[11] UTXBRK: Transmit Break bit // 1 = Send Break on next transmission. Start bit followed by twelve e0f bits, followed by Stop bit; // cleared by hardware upon completion // 0 = Break transmission is disabled or completed // UxSTA[10] UTXEN: Transmit Enable bit // 1 = UARTx transmitter is enabled. UxTX pin is controlled by UARTx (if ON = 1) // 0 = UARTx transmitter is disabled. Any pending transmission is aborted and buffer is reset. // UxTX pin is controlled by port. // UxSTA[9] UTXBF: Transmit Buffer Full Status bit (read-only) // 1 = Transmit buffer is full // 0 = Transmit buffer is not full, at least one more character can be written // UxSTA[8] TRMT: Transmit Shift Register is Empty bit (read-only) // 1 = Transmit shift register is empty and transmit buffer is empty (the last transmission has completed) // 0 = Transmit shift register is not empty, a transmission is in progress or queued in the transmit buffer // UxSTA[7-6] URXISEL<1:0>: Receive Interrupt Mode Selection bit // 11 = Reserved; do not use // 10 = Interrupt flag bit is asserted while receive buffer is 3/4 or more full (i.e., has 6 or more data characters) // 01 = Interrupt flag bit is asserted while receive buffer is 1/2 or more full (i.e., has 4 or more data characters) // 00 = Interrupt flag bit is asserted while receive buffer is not empty (i.e., has at least 1 data character) // UxSTA[5] ADDEN: Address Character Detect bit (bit 8 of received data = 1) // 1 = Address Detect mode is enabled. If 9-bit mode is not selected, this control bit has no effect // 0 = Address Detect mode is disabled // UxSTA[4] RIDLE: Receiver Idle bit (read-only) // 1 = Receiver is Idle // 0 = Data is being received // UxSTA[3] PERR: Parity Error Status bit (read-only) // 1 = Parity error has been detected for the current character // 0 = Parity error has not been detected // UxSTA[2] FERR: Framing Error Status bit (read-only) // 1 = Framing error has been detected for the current character // 0 = Framing error has not been detected // UxSTA[1] OERR: Receive Buffer Overrun Error Status bit. // This bit is set in hardware and can only be cleared (= 0) in software. // Clearing a previously set OERR bit resets the receiver buffer and RSR to empty state. // 1 = Receive buffer has overflowed // 0 = Receive buffer has not overflowed // UxSTA[0] URXDA: Receive Buffer Data Available bit (read-only) // 1 = Receive buffer has data, at least one more character can be read // 0 = Receive buffer is empty // ************************** U1STAbits.ADM_EN = 0; U1STAbits.UTXISEL1 = 0; U1STAbits.UTXISEL0 = 0; U1STAbits.UTXINV = 0; U1STAbits.URXEN = 0; U1STAbits.UTXBRK = 0; U1STAbits.UTXEN = 0; U1STAbits.URXISEL0 = 0; U1STAbits.URXISEL1 = 0; U1STAbits.ADDEN = 0; U1STAbits.OERR = 0; // ************************** // (4)Start UART // ************************** U1MODEbits.ON = 1; U1STAbits.UTXEN = 1; U1STAbits.URXEN = 1; } //****************************************************************************************** // Function Name : SendUARTStr // Title : Send UART Strings // Input : // Output : //****************************************************************************************** void SendUARTStr(unsigned char in_s[]) { unsigned char lp = 0; while(in_s[lp] != 0){ SendUART(in_s[lp]); lp++; } } //****************************************************************************************** // Function Name : SendUART // Title : Send UART // Input : // Output : //****************************************************************************************** void SendUART(unsigned char in_c) { while(U1STAbits.UTXBF != 0); U1TXREG = in_c; } //****************************************************************************************** // Function Name : RecUART // Title : Recive UART // Input : // Output : //****************************************************************************************** void RecUART(unsigned char *out_c) { while(U1STAbits.URXDA == 0); *out_c = U1RXREG; } //****************************************************************************************** // Function Name : wait_1mS // Title : // Input : 0.001[S] * n // Output : //****************************************************************************************** void wait_1mS(unsigned int no) { unsigned int lp; for(lp=0;lp 50nS //****************************************************************************************** void WaitNOP(void) { __asm__ ("nop"); __asm__ ("nop"); }