CCS C Software and Maintenance Offers
FAQFAQ   FAQForum Help   FAQOfficial CCS Support   SearchSearch  RegisterRegister 

ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 

CCS does not monitor this forum on a regular basis.

Please do not post bug reports on this forum. Send them to support@ccsinfo.com

Explorer16 w/24FJ128GA010, ENC28J60, using EX13B, add timer3

 
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion
View previous topic :: View next topic  
Author Message
pfournier



Joined: 30 Sep 2003
Posts: 89

View user's profile Send private message

Explorer16 w/24FJ128GA010, ENC28J60, using EX13B, add timer3
PostPosted: Mon May 12, 2014 1:10 pm     Reply with quote

I am using the CCS Compiler 5.025 (PCWHD) and the latest TCP/IP Stack v 5.42.

I recently bought the Explorer16 demo board with the ENC28J60.
Using the Example code (EX13B) from the CCS version of the stack I have TCP working just fine.

Now, in order to more closely emulate the system I expect to put this on, I added a Timer3 (running at about 100mS) interrupt to blink an LED. The LED blinks just fine, but when I use the timer interrupt I cannot connect!

Before I go too far I did the exact same thing with the CCS Embedded Ethernet kit using the 18F4620 and ENC28J60, so I assumed this would be a slam dunk!

I tried removing everything from the interrupt, I tried changing the LEVEL to 2 and even 1. The only reference I could find in the stack was in GenerateRandomByteFromTimers and I removed it from there.

I printed out all the Interrupt registers and they all looked fine.

I have no idea what the problem is.

Any clues?
_________________
-Pete
pfournier



Joined: 30 Sep 2003
Posts: 89

View user's profile Send private message

PostPosted: Mon Jun 02, 2014 9:14 am     Reply with quote

CCS Compiler 5.025 (PCWHD) and the latest TCP/IP Stack v 5.42.

I have solved this problem, though I am not quite sure as to the the nature of the problem.

I did some fix-ups in enc28j60.c, and ccstcpip.h.

The things I found when looking around were...

1. When the code went to read the SPI buffer, sometimes the SPI port reported there was already something in the buffer, then when you did a transmit/read pair you would get an overflow flag.
I noticed there was a ClearSPIDoneFlag() at the start of a function that was going to do a write/read to the SPI, but it was blank for the code that was used for the 24F processors (__C30__), so for the 24F, I always cleared the overflow flag and read the SPI buffer before doing anything.

2. I created a EmptySPIReceiveBuffer() macro that made sure the receive buffer was empty before leaving the write/read function
I used it in:
MACGet(), MACGetArray() (3 places), ReadETHReg(), ReadMACReg(), WriteReg(), BFCReg(), BFSReg()

3. Made a change in MACFlush. The original code waited 1000 loops waiting for transmission or reception to happen. Tuns out the loop count should have been MUCH bigger because the loops were going so fast (clock at 40MHZ) multiple retransmissions would happen.
THIS WAS THE ORIGINAL FIX THAT ALLOWED ME TO USE TIMER3 TO BLINK MY LED.



I had to add a
Code:
 volatile BYTE Dummy;
in the beginning of function in which 1 & 2 were added.

I had to add this to CSTCPIP.h to make may mods work with both 18F and 24f demos:
Code:

   //this is for my 24F
   #define ENC_SPISTATxbits   SPI1STATbits

  //this for my 18F
  #define ENC_SPISTATxbits SSPCON1bits
   #define ENC_SPISTAT SSPSTAT
   #define SPIRBF BF
   #define SPIROV SSPOV


I added
Code:
 ENC_SPISTATxbits.SPIROV = 0;
to the MACInit function just to make sure it is clear before we start.

Here is the code snippets. If anyone wants I can send you the whole file.

Around line 129 of enc28j60.c:

Some changes are to allow the compiler to complete without warnings.
Some changes are to allow the use of enhanced SPI (which did nothing for me as it turned out because I did not implement it fully), but I did not remove it because I was lazy and thought I might want to use it later.

Code:

#if defined (__18CXX)
    #define ClearSPIDoneFlag()  {ENC_SPI_IF = 0;}
    #define WaitForDataByte()   {while(!ENC_SPI_IF); ENC_SPI_IF = 0;}
    #define SPI_ON_BIT          (ENC_SPICON1bits.SSPEN)
#elif defined(__C30__)
    //#define ClearSPIDoneFlag()
    // added to ensure spi port is ready to xfer data PJF 5/19/14
    #define ClearSPIDoneFlag() {ENC_SPISTATxbits.SPIROV = 0; Dummy = ENC_SSPBUF;}

    //PJF put conditions here to avoid warnings since CCS does not recognize __always_inline__
    #ifdef __CCS__
       static inline void WaitForDataByte( void )
    #else
       static inline __attribute__((__always_inline__)) void WaitForDataByte( void )
    #endif
    {
      #ifdef ENHANCED_SPI
         while((ENC_SPISTATbits.SRXMPT == 1));
      #else
         while ((ENC_SPISTATbits.SPITBF == 1) || (ENC_SPISTATbits.SPIRBF == 0));
      #endif
    }

    #define SPI_ON_BIT          (ENC_SPISTATbits.SPIEN)
#elif defined( __PIC32MX__ )
    //#define ClearSPIDoneFlag()
    // added to ensure spi port is ready to xfer data PJF 5/19/14
    #define ClearSPIDoneFlag() {ENC_SPISTATxbits.SPIROV = 0; Dummy = ENC_SSPBUF;}

    //PJF put conditions here to avoid warnings since CCS does not recognize __always_inline__
    #ifdef __CCS__
       static inline void WaitForDataByte( void )
    #else
      static inline __attribute__((__always_inline__)) void WaitForDataByte( void )
   #endif
    {
        while (!ENC_SPISTATbits.SPITBE || !ENC_SPISTATbits.SPIRBF);
    }

    #define SPI_ON_BIT          (ENC_SPICON1bits.ON)
#else
    #error Determine SPI flag mechanism
#endif

#ifdef ENHANCED_SPI
   #define EmptySPIReceiveBuffer() {while(ENC_SPISTATbits.SRXMPT == 0) Dummy = ENC_SSPBUF;}//empty the buffer
#else
   #define EmptySPIReceiveBuffer() {while(ENC_SPISTATbits.SPIRBF == 1) Dummy = ENC_SSPBUF;}//empty the buffer
#endif






Around line 750 (MACFlush)

Code:

    if(ENCRevID == 0x05u || ENCRevID == 0x06u)
    {

/*   original code
        WORD AttemptCounter = 0x0000;
        while(!(ReadETHReg(EIR).Val & (EIR_TXERIF | EIR_TXIF)) && (++AttemptCounter < 1000u));
        if(ReadETHReg(EIR).EIRbits.TXERIF || (AttemptCounter >= 1000u))
        {
*/
        //need more time before deciding it failed PJF 5/20/14
        #define ATTEMPT_COUNT 1000000ul
        int32 AttemptCounter = 0x0000;
        //wait for trnasmission error or completed for ATTEMPT_COUNT tries
        while(!(ReadETHReg(EIR).Val & (EIR_TXERIF | EIR_TXIF)) && (++AttemptCounter < ATTEMPT_COUNT));
        if(ReadETHReg(EIR).EIRbits.TXERIF || (AttemptCounter >= ATTEMPT_COUNT))
        {



Example of the use of EmptySPIReceiveBuffer()

Code:

static REG ReadMACReg(BYTE Address)
{
    REG r;
    volatile BYTE Dummy;      //PJF 5/20/14

    ENC_CS_IO = 0;
    ClearSPIDoneFlag();
    ENC_SSPBUF = RCR | Address; // Send the Read Control Register opcode and
                                //   address.
    WaitForDataByte();          // Wait until opcode/address is transmitted.
    r.Val = ENC_SSPBUF;
    ENC_SSPBUF = 0;             // Send a dummy byte
    WaitForDataByte();          // Wait for the dummy byte to be transmitted
    r.Val = ENC_SSPBUF;
    ENC_SSPBUF = 0;             // Send another dummy byte to receive the register
                                //   contents.
    WaitForDataByte();          // Wait until register is received.
    r.Val = ENC_SSPBUF;                           

    EmptySPIReceiveBuffer(); // PJF 5/23/14

    ENC_CS_IO = 1;

    return r;
}//end ReadMACReg

_________________
-Pete
Display posts from previous:   
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion All times are GMT - 6 Hours
Page 1 of 1

 
Jump to:  
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum


Powered by phpBB © 2001, 2005 phpBB Group