|
|
View previous topic :: View next topic |
Author |
Message |
pfournier
Joined: 30 Sep 2003 Posts: 89
|
Explorer16 w/24FJ128GA010, ENC28J60, using EX13B, add timer3 |
Posted: Mon May 12, 2014 1:10 pm |
|
|
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
|
|
Posted: Mon Jun 02, 2014 9:14 am |
|
|
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 |
|
|
|
|
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
|