This page describes the steps required to adapt the standard Microchip TCPIP Library (V5.25 as supplied with ‘Microchip Application Library 20100428′) to function on the Plug & Program NetSat1.

Refer to the NetSat1 page for details on modules included.


Summary of steps:

Part 1:  Environment and application library setup

  • Setup workstation required software (MPLAB)
  • Install Microchip Application library
  • Add PlugAndProgram ethernet bootloader procdefs.ld if using bootloader

Part 2: Working project targeted for minimum working web server PlugAndProgram hardware

  • Add MC32MX64GP.h
  • Map TCPIP Stack Application to MC32MX64GP hardware (HardwareProfile.h)
  • Configure TCPIP stack application (TCPIPConfig.h)
    • Included modules
    • Data Storage Options
    • Hostname & IP Addressing

Part 1:  Workstation IDE and application library setup

Install latest MPLAB (included C 32 compiler included)

Install Microchip application library V20100428

  • Copy the installed Microchip application library to a working folder ie e:\PlugAndProgram 5.25 Minimal\
  • (Optional) Remove all \PlugAndProgram 5.25 Minimal\.. sub folders except:
    • \PlugAndProgram 5.25 Minimal\Microchip\
    • \PlugAndProgram 5.25 Minimal\TCPIP ENCX24J600 Demo App\
  • (Optional) Delete all the *.hex files from folder \PlugAndProgram 5.25 Minimal\TCPIP ENCX24J600 Demo App\..

If you will be using the Ethernet bootloader preloaded onto the PlugAndProgram MC32MX64GP you will need to copy the bootloader procdefs.ld file into folder \PlugAndProgram 5.25 Minimal\TCPIP ENCX24J600 Demo App\

(If you will be using your own ICSP compatible Microchip programmer you will not want to include this file)

Part 2: Working project targeted for a working web server on PlugAndProgram netSat1 hardware

Note: Web pages will be stored on the PNP-MEMFL32 flash memory module

Open the project and select the target processor:

  • MPLab -> Project -> Open: \PlugAndProgram 5.25 Minimal\TCPIP ENCX24J600 Demo App\TCPIP ENCX24J600 Demo App-C32.mcp
  • MPLab -> Project -> Build All: should build ok
  • MPLab -> Configure -> Select Device: PIC32MX340F512H

Add standard MC32MX64GP  hardware defines file (MC32MX64GP.h):

  • MPLab -> File -> Add New File To Project: \PlugAndProgram 5.25 Minimal\TCPIP ENCX24J600 Demo App\MC32MX64GP.h
  • Copy / Paste in MC32MX64GP.h standard hardware defines

Map TCPIP Stack application to MC32MX64GP hardware:

  • MPlab -> Window -> ENCX24J600 Demo App-C32.mcw: Open HardwareProfile.h
  • Copy / Paste  replacing existing HardwareProfile.h contents with:

 #include "GenericTypeDefs.h"
 #include "Compiler.h"

 #include "MC32MX64GP.h"

 // Map TCPIP Stack defins to MC32MXGP64 Hardware

 // PlugAndProgram Modules: PNP-LED4R & PNP-LED4L
 // TCPIP Stack LED0-3 via PNP-LED4R.IO-In connected to MC32MX64GP.IO8
 // TCPIP Stack LED4-7 via PNP-LED4L.IO-In connected to MC32MX64GP.IO9
 #define LED0_TRIS (IO8_1TRIS) // Ref PNP-LED4R LED1
 #define LED0_IO (IO8_1LAT)
 #define LED1_TRIS (IO8_2TRIS) // Ref PNP-LED4R LED2
 #define LED1_IO (IO8_2LAT)
 #define LED2_TRIS (IO8_3TRIS) // Ref PNP-LED4R LED3
 #define LED2_IO (IO8_3LAT)
 #define LED3_TRIS (IO8_4TRIS) // Ref PNP-LED4R LED4
 #define LED3_IO (IO8_4LAT)
 #define LED4_TRIS (IO9_1TRIS) // Ref PNP-LED4L LED1
 #define LED4_IO (IO9_1LAT)
 #define LED5_TRIS (IO9_2TRIS) // Ref PNP-LED4L LED2
 #define LED5_IO (IO9_2LAT)
 #define LED6_TRIS (IO9_3TRIS) // Ref PNP-LED4L LED3
 #define LED6_IO (IO9_3LAT)
 #define LED7_TRIS (IO9_4TRIS) // Ref PNP-LED4L LED4
 #define LED7_IO (IO9_4LAT)

 #define LED_GET() ((LED4_IO<<4) | (LED7_IO<<7) | (LED6_IO<<6)| (LED5_IO<<5) | (LED4_IO<<4) | LED3_IO<<3) | (LED2_IO<<2) | (LED1_IO<<1) | LED0_IO)
 #define LED_PUT(a) do{BYTE vTemp = (a); LED0_IO = vTemp&0x1; LED1_IO = vTemp&0x2; LED2_IO = vTemp&0x4; LED3_IO = vTemp&0x8; LED4_IO = vTemp&0x16; LED5_IO = vTemp&0x32; LED6_IO = vTemp&0x64; LED7_IO = vTemp&0x16;} while(0)

 //PlugAndProgram Modules: PNP-TACT4
 //TCPIP Stack Button0-3 on PNP-TACT4 connected to MC32MX64GP.IO11
 #define BUTTON0_TRIS (IO11_1TRIS) // Ref PNP-TACT4 S1
 #define BUTTON0_IO (IO11_1)
 #define BUTTON1_TRIS (IO11_2TRIS) // Ref PNP-TACT4 S2
 #define BUTTON1_IO (IO11_2)
 #define BUTTON2_TRIS (IO11_3TRIS) // Ref PNP-TACT4 S3
 #define BUTTON2_IO (IO11_3)
 #define BUTTON3_TRIS (IO11_4TRIS) // Ref PNP-TACT4 S4
 #define BUTTON3_IO (IO11_4)

 // PlugAndProgram Modules: PNP-ETH424 (ENC424J600)
 // TCPIP Stack ENC424J600 via
 // - PNP-ETH424.IO-SPI connected to PNP-SPI+4B.IO-SPI-Out,
 // - PNP-SPI+4B.IO-SPI-In connected to MC32MX64GP.IO1 (SPI2)
 // Note re use of PNP-SPI+4B module:
 //      If MC32MX64GP.IO1 is connected to PNP-SPI+4B.IO-SPI-In,
 //      and PNP-ETH424.IO-SPI is connected to PNP-SPI+4B.IO-SPI-Out, this is identical to
 //      MC32MX64GP.IO1 connecting directly to PNP-ETH424.IO-SPI
 // - So Chip select is MC32MX64GP.IO1.4
 #define ENC100_INTERFACE_MODE 0    // - 0: SPI mode using CS, SCK, SI, and SO pins
 #define ENC100_CS_TRIS (IO1_SS2TRIS) // CS is mandatory when using the SPI interface
 #define ENC100_CS_IO (IO1_SS2LAT)
 #define ENC100_SO_WR_B0SEL_EN_IO (IO1_SDI2)
 #define ENC100_SI_RD_RW_TRIS (IO1_SDO2TRIS)
 #define ENC100_SI_RD_RW_IO (IO1_SDI2LAT)
 // ENC624J600 SPI SFR register selection
 #define ENC100_SPI_ENABLE (ENC100_SPICON2bits.ON)
 #define ENC100_SSPBUF (SPI2BUF)
 #define ENC100_SPICON1 (SPI2CON)
 #define ENC100_SPISTATbits (SPI2STATbits)
 #define ENC100_SPICON1bits (SPI2CONbits)
 #define ENC100_SPIBRG (SPI2BRG)

 // PlugAndProgram Modules: PNP-LCD16X2
 // PNP-LCD16X2.IO-Control connected to MC32MX64GP.IO10
 // IO10.1 = E
 // IO10.2 = RW
 // IO10.3 = RS
 // IO10.4 = Backlight (1 = on, 0 = off)
 #define USE_LCD
 #define LCD_E_TRIS (IO10_1TRIS)
 #define LCD_E_IO (IO10_1LAT)
 #define LCD_RD_WR_TRIS (IO10_2TRIS)
 #define LCD_RD_WR_IO (IO10_2LAT)
 #define LCD_RS_TRIS (IO10_3TRIS)
 #define LCD_RS_IO (IO10_3LAT)
 #define LCD_BL_TRIS (IO10_4TRIS)
 #define LCD_BL (IO10_4LAT)
 // LCD Data pins on MC32MX64GP.IO10
 // Only 4 pins defined because we will drive the LCD in 4bit mode
 #define LCD_DATA0_TRIS (IO12_1TRIS)
 #define LCD_DATA0_IO (IO12_1)
 #define LCD_DATA1_TRIS (IO12_2TRIS)
 #define LCD_DATA1_IO (IO12_2LAT)
 #define LCD_DATA2_TRIS (IO12_3TRIS)
 #define LCD_DATA2_IO (IO12_3LAT)
 #define LCD_DATA3_TRIS (IO12_4TRIS)
 #define LCD_DATA3_IO (IO12_4LAT)

 // PlugAndProgram Modules: PNP-MEMFL32 (SST25VF032B)
 // TCPIP Stack SPIFlash via:
 // - PNP-MEMFL32.IO-SPI connected to PNP-SPI+4B.IO-Slave1,
 // - PNP-SPI+4B.IO-SPI-In connected to MC32MX64GP.IO1 (SPI2)
 // - PNP-SPI+4B.IO-SS-In connected to MC32MX64GP.IO4
 // - So Chip select is MC32MX64GP.IO4.1
 #define SPIFLASH_CS_IO (IO4_4LAT)
 // SPIFlash SPI SFR register selection
 #define SPIFLASH_SPICON1bits (SPI2CONbits)
 #define SPIFLASH_SPISTATbits (SPI2STATbits)

 // PlugAndProgram Modules: PNP-MEMEE512 (25LC512)
 // TCPIP Stack EEPROM via:
 // - PNP-MEMFL32.IO-SPI connected to PNP-SPI+4B.IO-Slave2,
 // - PNP-SPI+4B.IO-SPI-In connected to MC32MX64GP.IO1 (SPI2)
 // - PNP-SPI+4B.IO-SS-In connected to MC32MX64GP.IO4
 // - So Chip select is MC32MX64GP.IO4.2
 #define EEPROM_CS_TRIS        (IO4_3TRIS)
 #define EEPROM_CS_IO        (IO4_3LAT)
 #define EEPROM_SCK_TRIS        (IO1_SCK2TRIS)
 #define EEPROM_SDI_TRIS        (IO1_SDI2TRIS)
 #define EEPROM_SDO_TRIS        (IO1_SDO2TRIS)
 // EEPROM SPI SFR register selection
 #define EEPROM_SPI_IF        (IFS1bits.SPI2RXIF)
 #define EEPROM_SSPBUF        (SPI2BUF)
 #define EEPROM_SPICON1        (SPI2CON)
 #define EEPROM_SPICON1bits    (SPI2CONbits)
 #define EEPROM_SPIBRG        (SPI2BRG)
 #define EEPROM_SPISTAT        (SPI2STAT)
 #define EEPROM_SPISTATbits    (SPI2STATbits)

 // MC32MX64GP.IO5 (UART2)
 // PNP-USB2Serial connected to MC32MX64GP.IO5 otherwise leave this block commented out
 // (TCPIPConfig.h modules STACK_USE_UART and STACK_USE_UART2TCP_BRIDGE need to be commented out as well)
 #define UARTTX_TRIS (IO5_U2TX)
 #define UARTRX_TRIS (IO5_U2RX)

 #define UBRG                    U2BRG
 #define UMODE                    U2MODE
 #define USTA                    U2STA
 #define BusyUART()                BusyUART2()
 #define CloseUART()                CloseUART2()
 #define ConfigIntUART(a)        ConfigIntUART2(a)
 #define DataRdyUART()            DataRdyUART2()
 #define OpenUART(a,b,c)            OpenUART2(a,b,c)
 #define ReadUART()                ReadUART2()
 #define WriteUART(a)            WriteUART2(a)
 #define getsUART(a,b,c)            getsUART2(a,b,c)
 #define putsUART(a)                putsUART2(a)
 #define getcUART()                getcUART2()
 #define putcUART(a)                do{while(BusyUART()); WriteUART(a); while(BusyUART()); }while(0)
 #define putrsUART(a)            putrsUART2(a)



Setup LCD library for PNP-LCD16X2 module

  • MPlab -> Window -> ENCX24J600 Demo App-C32.mcw: Open LCDBlocking.c
  • Uncomment
  • Comment
//#define SAMSUNG_S6A0032

Setup SPIFlash library for our hardware

  • MPlab -> Window -> ENCX24J600 Demo App-C32.mcw: Open SPIFlash.c
  • Set SPI speed
#define SPIFLASH_MAX_SPI_FREQ       (5000000ul)

Setup EEPROM library for our hardware

  • MPlab -> Window -> ENCX24J600 Demo App-C32.mcw: Open SPIEEPROM.c
  • Set SPI speed
#define EEPROM_MAX_SPI_FREQ     (5000000ul)    // Hz

Setup ENC424J600 library

  • MPlab -> Window -> ENCX24J600 Demo App-C32.mcw: Open ENCX24J600.c
  • Set SPI speed
#define ENC100_MAX_SPI_FREQ        (5000000ul)    // Hz

Configure the TCPIP Stack:

  • MPlab -> Window -> ENCX24J600 Demo App-C32.mcw: Open TCPIPConfig.h
  • Comment out UART modules in the ‘Application Options’ section:
#define STACK_USE_UART     // Application demo using UART for IP address display and stack configuration
#define STACK_USE_UART2TCP_BRIDGE  // UART to TCP Bridge application example
  • If you want to use a fixed IP Address (ie do not use your network DHCP server to dynamically allocate an IP address comment out (in the ‘Application Options’ section):
  • To store our webpages in the PNP-MEMFL32 flash memory module, in  ‘Data Storage Options’ section:
  • The PNP-MEMFL32 SST25VF032B flash IC works in 4096 byte erase blocks:
#define MPFS_RESERVE_BLOCK                (4096ul)
  • Define your hostname in ‘Network Addressing Options’ section:
  • Define your fixed IP address, gateway, DNS servers as required if  not using DHCP client module per above, example:
#define MY_DEFAULT_IP_ADDR_BYTE1        (192ul)
#define MY_DEFAULT_IP_ADDR_BYTE2        (168ul)
#define MY_DEFAULT_IP_ADDR_BYTE3        (1ul)
#define MY_DEFAULT_IP_ADDR_BYTE4        (150ul)

#define MY_DEFAULT_MASK_BYTE1           (255ul)
#define MY_DEFAULT_MASK_BYTE2           (255ul)
#define MY_DEFAULT_MASK_BYTE3           (0ul)
#define MY_DEFAULT_MASK_BYTE4           (0ul)

 #define MY_DEFAULT_GATE_BYTE1           (192ul)
#define MY_DEFAULT_GATE_BYTE2           (168ul)
#define MY_DEFAULT_GATE_BYTE3           (1ul)
#define MY_DEFAULT_GATE_BYTE4           (1ul)



Add in additional initialisation code to MainDemo.c

  • MPlab -> Window -> ENCX24J600 Demo App-C32.mcw: Open MainDemo.c
  • Immediately after ‘InitializeBoard();’ add:
// PlugAndProgram Initialisation Start
// Turn on LCD Backlight
#if defined(USE_LCD)
    LCD_BL_TRIS = 0;
    LCD_BL = 1;
//Turn off Analogue
//MC32MX64GP.IO4 & IO1_SS2 Put SPI SS IO to output and all high
IO4_1LAT = IO4_2LAT = IO4_3LAT = IO4_4LAT = IO1_SS2LAT = 1 ;
IO4_1TRIS = IO4_2TRIS = IO4_3TRIS = IO4_4TRIS = IO1_SS2TRIS = 0 ;
// PlugAndProgram Initialisation END
  • Immediately after this (Just prior to main loop starting):

insert this is configure the AD convertor

// PlugAndProgram Analoge to Digital Initialisation Start
 // Configure AD module
 // First set all registers except AD1PCFGCLR back to POR State ie all cleared as we dont know what the
 // TCPIP Initalisation routines have done or will do in future revisions
 AD1CON1CLR = 0xFFFFFFFF; // This will also turn off the AD module if it was already on (bit 15)

 AD1PCFGSET = 0xFFFFFFFF; // Turn off all Analogue

 // The following sequence and identifiers (A-1) etc are per the PIC32MX ADC reference manual steps
 // for chapter 17.4 ADC Module configuration (Microchip doc ref DS61104D)

 // A-1: Select Analogue inputs by clearing applicable pin bits in AD1PCFG<15:0> and also by setting applicable TRIS bits (Configure as input)
 //AD1PCFGCLR = 0x0000000F; // Turn on AN0-3  // Because we are using scan mode it is AD1CSSLSET that defines the input channels..

 //Set Digital IO for AN0-AN3 to Inputs
 TRISBbits.TRISB0 = 1;
 TRISBbits.TRISB1 = 1;
 TRISBbits.TRISB2 = 1;
 TRISBbits.TRISB3 = 1;

 // B-1: Select ADC MUX per analogue input in ADCHS<32:0>
 // By default MUX input channel selects are cleared means MUX A & B -ve input is VR-
 // Connect AN0 as +ve input to CH0SA (MUX A)
 // For CH0SA is AD1CHSSET bits 19-16, ie 0 = AN0, 1 = AN1... 15 = AN16
 // Note that in SCAN mode CH0SA is ignored
 // AD1CHSSET = 0x00000000;  // No change but we will leave this as an example/template

 // C-1: Select output format of result in FORM<2:0> (AD1CON1<10:8>)
 // We simply want our 10 bit integers.. so will select a 16bit integer which is the default..
 // ADCON1SET = 0x00000000 // No change but we will leave this as an example/template

 // C-2: Select sample clock source using SSRC<2:0> (AD1CON1<7:5>)
 // *** With scan we shouldn't need to set these? But we will just in case.. ***
 //AD1CON1SET = 0x00000070; // We want to autoconvert across our selected channels so SSRC = 111
 AD1CON1bits.SSRC = 0b111;
 //AD1CON1SET = 0x00000002; // We want autosampling so need ASAM (AD1CON1<2> set)
 AD1CON1bits.ASAM = 0b1;

 // D-1: Select voltage reference source for VR+ & VR- using VCFG<2:0>  (AD1CON2<15:13>)
 //AD1CON2SET 0x00000000; // Default = 000 = VR+ = AVdd, VR- = AVss so no change but we will leave this as an example/template
 AD1CON2bits.VCFG = 0b000;

 // D-2: Select scan mode using CSCNA (AD1CON2<10>)
 //AD1CON2SET = 0x00000400;
 AD1CON2bits.CSCNA = 0b1;
 AD1CSSLSET = 0x0000000F; // Scan AN0-3

 // D-3 Set the number of conversions per interrupt (if interrupts are to be used) using SMPI<3:0> (AD1CON2<5:2>)
 //AD1CON2SET = 0x0000000C; // We will setup to use all 16 buffers regardless of the no of inpuits we are scanning
 AD1CON2bits.SMPI = 0b1111;

 // D-4: Set buffer fill mode using BUFM (AD1CON2<1>)
 //AD1CON2SET = 0x00000002;    // we will leave as 0 ie 16 sequential buffers
 //AD1CON2bits.BUFM = 0b0;

 // D-5: Select the MUX to be connected to the ADC in ALTS (AD1CON2<0>)
 // We have no need to use ALTS at this time so will accept the default (ALTS = 0) for Single input selection
 // AD1CON2SET = 0x00000000; no change but we will leave this as an example/template
 //AD1CON2bits.ALTS = 0b0;

 //E-1: Select ADC Clock source using ADRC (AD1Con3<15>)
 AD1CON3bits.ADRC = 0b1;

 // E-2: Select the sample time using SAMC<4:0> (AD1CON3<12:8>) if autoconvert is to be used
 AD1CON3bits.SAMC = 0b11111; // We will wait for the longest time..

 // E-3: Select the ADC clock prescaler using ADCS<7:0> (AD1CON3<7:0>
 // As we are using the Internal RC this is ignored
 //AD1CON3bits.ADRC = 0b0;

 // Now Turn on ADC:
 AD1CON1bits.ON = 1;

 // PlugAndProgram Analog to Digital Initialisation END

Build your project and load it into your MC32MX64GP mainboard