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 CCS Technical Support

PIC24 + enc28j60 freeze
Goto page 1, 2  Next
 
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion
View previous topic :: View next topic  
Author Message
pomakmrysen



Joined: 14 Sep 2017
Posts: 10

View user's profile Send private message

PIC24 + enc28j60 freeze
PostPosted: Thu Sep 14, 2017 10:40 am     Reply with quote

Hello,

I tried to use PIC24FJ128GA202 with enc28j60 and tcp/ip library but the pic freezes. This is my code:

Code:

#include <main.h>

#include <ctype.h>
#include <errno.h>
#include <float.h>
#include <stdio.h>


/* TODO: Web server enabled. Server files are added to the /pages
directory. You can modify the contents of the dynamic display fields
at the end of the index.htm file. By default, headings are in the left
column and the dynamic display elements are in the right. The text on
the input buttons can be set by changing the 'value' strings in the
form section. Dynamic display elements can be added or removed from
index.htm and index.xml */
/* TODO: Server files must be built into an MPFS image prior to
compiling and runing the web server. Running makempfsimg.bat in the
/mpfs directory will create an MPFS image of the files in /pages.
A new MPFS image has to be compiled and re-loaded if a file in
/pages needs to be changed. */

unsigned int8 http_format_char(char* file, char id, char *str, unsigned int8 max_ret)
{
   /* TODO: This is a callback function to the HTTP stack.
   'id' is the char for the dynamic element to be updated.
   For each dynamic element you create, you need to parse
   and save a result to 'str'. *str is where the callback
   function must save the formatting result, and it should
   not store more than max_ret characters to this pointer
   (buffer-overrun protection).
   Example:
   switch(id) {
      case 0x00:
         set_adc_channel(0);
         delay_us(100);
         i=read_adc();
         sprintf(new_str,"0x%X", i);
   .....
   strncpy(str, new_str, max_ret);
   */

   *str = 0;

   if (id == 0)
   {
         //TODO: Handle dyn0 field and save result to str
   }
   if (id == 1)
   {
         //TODO: Handle dyn1 field and save result to str
   }

   return(strlen(str));
}

void http_exec_cgi(char* file, char *key, char *val)
{
   /* TODO: This is a callback function to the HTTP stack.
   This function is called with each key/value pair read in
   the GET/POST request before any web data is sent to the
   web browser. 'key' matches the name of the field and
   'val' is the value it was changed to.
   Example:
   int8 v = atoi(val);
   if (stricmp(key,led1_key)==0)
      LedSet(0, v);
   */
   if (strcmp(key, "button00") == 0)
   {
      //TODO: Handle button00
   }
   if (strcmp(key, "button01") == 0)
   {
      //TODO: Handle button01
   }

}

void StackPrintfChanges(void)
{
   static enum {PRINT_INIT=0, PRINT_NO_MAC, PRINT_NO_DHCP, PRINT_IDLE} state=0;

   switch(state)
   {
      case PRINT_INIT:
         printf("\n\rNo MAC Link: %X:%X:%X:%X:%X:%X", MY_MAC_BYTE1, MY_MAC_BYTE2, MY_MAC_BYTE3, MY_MAC_BYTE4, MY_MAC_BYTE5, MY_MAC_BYTE6);
         state = PRINT_NO_MAC;
         break;

      case PRINT_NO_MAC:
         if (MACIsLinked())
         {
           #if defined(STACK_USE_DHCP_CLIENT)
            if (!DHCPIsEnabled(0))
           #else
            if (0)
           #endif
            {
               printf("\n\rDHCP Disabled: %u.%u.%u.%u", MY_IP_BYTE1, MY_IP_BYTE2, MY_IP_BYTE3, MY_IP_BYTE4);
               state = PRINT_IDLE;
            }
            else
            {
               printf("\n\rDHCP Not Bound");
               state = PRINT_NO_DHCP;
            }
         }
         break;

     #if defined(STACK_USE_DHCP_CLIENT)
      case PRINT_NO_DHCP:
         if (!MACIsLinked())
         {
            state = PRINT_INIT;
            break;
         }
         if (DHCPIsBound(0))
         {
            state = PRINT_IDLE;
            printf("\n\rDHCP Bound: %u.%u.%u.%u", MY_IP_BYTE1, MY_IP_BYTE2, MY_IP_BYTE3, MY_IP_BYTE4);
         }
         break;
     #endif

      case PRINT_IDLE:
         if (
               !MACIsLinked()
              #if defined(STACK_USE_DHCP_CLIENT)
               || (DHCPIsEnabled(0) && !DHCPIsBound(0))
              #endif
            )
         {
            state = PRINT_INIT;
         }
         break;
   }
}

void IPAddressInit(void)
{
   //MAC address of this unit
   MY_MAC_BYTE1=MY_DEFAULT_MAC_BYTE1;
   MY_MAC_BYTE2=MY_DEFAULT_MAC_BYTE2;
   MY_MAC_BYTE3=MY_DEFAULT_MAC_BYTE3;
   MY_MAC_BYTE4=MY_DEFAULT_MAC_BYTE4;
   MY_MAC_BYTE5=MY_DEFAULT_MAC_BYTE5;
   MY_MAC_BYTE6=MY_DEFAULT_MAC_BYTE6;

   //IP address of this unit
   MY_IP_BYTE1=MY_DEFAULT_IP_ADDR_BYTE1;
   MY_IP_BYTE2=MY_DEFAULT_IP_ADDR_BYTE2;
   MY_IP_BYTE3=MY_DEFAULT_IP_ADDR_BYTE3;
   MY_IP_BYTE4=MY_DEFAULT_IP_ADDR_BYTE4;

   //network gateway
   MY_GATE_BYTE1=MY_DEFAULT_GATE_BYTE1;
   MY_GATE_BYTE2=MY_DEFAULT_GATE_BYTE2;
   MY_GATE_BYTE3=MY_DEFAULT_GATE_BYTE3;
   MY_GATE_BYTE4=MY_DEFAULT_GATE_BYTE4;

   //subnet mask
   MY_MASK_BYTE1=MY_DEFAULT_MASK_BYTE1;
   MY_MASK_BYTE2=MY_DEFAULT_MASK_BYTE2;
   MY_MASK_BYTE3=MY_DEFAULT_MASK_BYTE3;
   MY_MASK_BYTE4=MY_DEFAULT_MASK_BYTE4;
}


void main()
{

   setup_adc_ports(sAN0, VSS_VDD);
   setup_adc(ADC_OFF | ADC_TAD_MUL_0);

   IPAddressInit();
   TickInit();
   enable_interrupts(GLOBAL);
   StackInit();


   while(TRUE)
   {

     // StackTask();

      //StackPrintfChanges();

     // StackApplications();
       
       
       delay_ms(1000);
       output_high(PIN_B15);
       delay_ms(1000);
       output_low(PIN_B15);
       
      //TODO: User Code
   }

}

and header file:
Code:

#include <24FJ128GA202.h>
#device ADC=8
#device ICD=TRUE
#device ICSP=2

/*
TCP/IP Stack enabled.
Many TCP/IP configuration settings (servers enabled, ports used,
etc) are defined in TCPIPConfig.h.
Many hardware configuration settings (SPI port and GPIO pins used)
are defined in HardwareProfile.h.
*/

#include "tcpip/PCDxxxx.h"

#define __PIC24F__

#define __C30__

#define WIFI_MAX_SSID 32

#include <stdint.h>
#use delay(clock=8MHz,crystal=8MHz)

#FUSES NOWDT                    //No Watch Dog Timer
#FUSES NOWINDIS                 //Watch Dog Timer in Window mode
#FUSES NOLVR                    //Low Voltage Regulator Disabled
#FUSES NOWRT                    //Program memory not write protected
#FUSES NOPROTECT                //Code not protected from reading
#FUSES NOJTAG                   //JTAG disabled
#FUSES WDTCLK_LPRC              //WDT uses LPRC as clock source
#FUSES NOOSCIO                  //OSC2 is clock output
#FUSES CKSFSM                   //Clock Switching is enabled, fail Safe clock monitor is enabled
#FUSES NOALTCMPI                //Comparator inputs are on their default pin locations
#FUSES WDTCMX                   //WDT clock source is determined by the WDTCLK configuration fuses
#FUSES WPFP                     //Write/Erase Protect Page Start/End Location, set to last page or use WPFP=x to set page
#FUSES SOSC_SEL                 //SOSC circuit selected
#FUSES WDTWIN_25%               //Watchdog Window is 25% of WDT period
#FUSES PLL_FROM_PRIMARY         //PLL is fed by the Primary oscillator
#FUSES NOBROWNOUT               //No brownout reset
#FUSES WPDIS                    //All Flash memory may be erased or written
#FUSES NOWPCFG                  //Configuration Words page is not erase/write-protected
#FUSES WPEND                    //Flash pages WPFP to Configuration Words page are write/erase protected
#FUSES DSWDTCK_LPRC             //DSWDT uses LPRC as reference clock
#FUSES DSBOR                    //BOR enabled in Deep Sleep
#FUSES DSWDT                    //Deep Sleep Watchdog Timer enabled
#FUSES DS_SW                    //Deep Sleep is controlled by the register bit DSEN
#FUSES NOPLL                    //HW PLL disabled
#FUSES NOALTI2C1                //I2C1 mapped to SDA1/SCL1 pins                //Allows only one reconfiguration of peripheral pins

#pin_select U1TX=PIN_B1
#pin_select U1RX=PIN_B2
#use rs232(UART1, baud=9600, stream=UART_PORT1)


#define MIN(a,b)  ((a > b) ? b : a)
#define wf_debug_printf(a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p)

#include "tcpip/TCPIPConfig.h"
#include "tcpip/HardwareProfile.h"
#include "tcpip/StackTsk2.h"

#if TCP_CONFIGURATION > 0
   TCPSocketInitializer_t TCPSocketInitializer[TCP_CONFIGURATION] =
   {
      #if defined(STACK_USE_CCS_HTTP2_SERVER)
         {TCP_PURPOSE_HTTP_SERVER, TCP_ETH_RAM, STACK_CCS_HTTP2_SERVER_TX_SIZE, STACK_CCS_HTTP2_SERVER_RX_SIZE},
      #endif
      #if defined(STACK_USE_SMTP_CLIENT)
         {TCP_PURPOSE_DEFAULT, TCP_ETH_RAM, STACK_CCS_SMTP_TX_SIZE, STACK_CCS_SMTP_RX_SIZE},
      #endif
      #if defined(STACK_USE_MY_TELNET_SERVER)
         {TCP_PURPOSE_TELNET, TCP_ETH_RAM, STACK_MY_TELNET_SERVER_TX_SIZE, STACK_MY_TELNET_SERVER_RX_SIZE},
      #endif
      #if defined(STACK_USE_CCS_HTTP_CLIENT)
         {TCP_PURPOSE_GENERIC_TCP_CLIENT, TCP_ETH_RAM, STACK_MY_HTTPC_TX_SIZE, STACK_MY_HTTPC_RX_SIZE},
      #endif
   };
#else
   #undef TCP_CONFIGURATION
   #define TCP_CONFIGURATION 1
   TCPSocketInitializer_t TCPSocketInitializer[TCP_CONFIGURATION] =
   {
      {TCP_PURPOSE_DEFAULT, TCP_ETH_RAM, 250, 250}
   };
#endif

#include "tcpip/StackTsk2.c"


Debugger shows it freezes on this line in Helpers.c file:
Code:
while(!IFS0bits.AD1IF);

Interrupt flag is not set. When i comment this it continues but freezes on this:
Code:

WaitForDataByte();

in ENC28J60.c on this function
Code:

static unsigned int16 _EncSpiXfer16(unsigned int16 word)
{
   ClearSPIDoneFlag();
   ENC_SSPBUF = word;
   WaitForDataByte();
   word = ENC_SSPBUF;
   return(word);
}


Anyone some suggestions ?
Ttelmah



Joined: 11 Mar 2010
Posts: 19553

View user's profile Send private message

PostPosted: Thu Sep 14, 2017 10:50 am     Reply with quote

As a general comment, before anything else, all of this:
Code:

#use delay(clock=8MHz,crystal=8MHz)

#FUSES NOWDT                    //No Watch Dog Timer
#FUSES NOWINDIS                 //Watch Dog Timer in Window mode
#FUSES NOLVR                    //Low Voltage Regulator Disabled
#FUSES NOWRT                    //Program memory not write protected
#FUSES NOPROTECT                //Code not protected from reading
#FUSES NOJTAG                   //JTAG disabled
#FUSES WDTCLK_LPRC              //WDT uses LPRC as clock source
#FUSES NOOSCIO                  //OSC2 is clock output
#FUSES CKSFSM                   //Clock Switching is enabled, fail Safe clock monitor is enabled
#FUSES NOALTCMPI                //Comparator inputs are on their default pin locations
#FUSES WDTCMX                   //WDT clock source is determined by the WDTCLK configuration fuses
#FUSES WPFP                     //Write/Erase Protect Page Start/End Location, set to last page or use WPFP=x to set page
#FUSES SOSC_SEL                 //SOSC circuit selected
#FUSES WDTWIN_25%               //Watchdog Window is 25% of WDT period
#FUSES PLL_FROM_PRIMARY         //PLL is fed by the Primary oscillator
#FUSES NOBROWNOUT               //No brownout reset
#FUSES WPDIS                    //All Flash memory may be erased or written
#FUSES NOWPCFG                  //Configuration Words page is not erase/write-protected
#FUSES WPEND                    //Flash pages WPFP to Configuration Words page are write/erase protected
#FUSES DSWDTCK_LPRC             //DSWDT uses LPRC as reference clock
#FUSES DSBOR                    //BOR enabled in Deep Sleep
#FUSES DSWDT                    //Deep Sleep Watchdog Timer enabled
#FUSES DS_SW                    //Deep Sleep is controlled by the register bit DSEN
#FUSES NOPLL                    //HW PLL disabled
#FUSES NOALTI2C1                //I2C1 mapped to SDA1/SCL1 pins                //Allows only one reconfiguration of peripheral pins

#pin_select U1TX=PIN_B1
#pin_select U1RX=PIN_B2
#use rs232(UART1, baud=9600, stream=UART_PORT1)


Should be before the includes.

Otherwise things that are dependant on serial, timings etc., may not work right.....

Generally, I'd be checking that the wiring is correct to the ENC. Try some basic tests reading and writing a register first.
pomakmrysen



Joined: 14 Sep 2017
Posts: 10

View user's profile Send private message

PostPosted: Thu Sep 14, 2017 10:56 am     Reply with quote

Connections are ok, checked many times...
temtronic



Joined: 01 Jul 2010
Posts: 9246
Location: Greensville,Ontario

View user's profile Send private message

PostPosted: Thu Sep 14, 2017 11:08 am     Reply with quote

pomakmrysen wrote:
#use rs232(UART1, baud=9600, stream=UART_PORT1)

You should always add 'errors' to the use_rs232(...options.....)

also.

Using a 'debugger' may (can) change various registers and operations of the PIC.
Have you confirmed you CAN read/write to ALL registers ?

Have you tried a 2nd ENC device ?

Is the PIC running at the correct speed ?

Jay
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Thu Sep 14, 2017 4:17 pm     Reply with quote

Quote:
Connections are ok, checked many times...

Check the connections between the PIC and the ENC with an ohmmeter
and post the list of connections.
Post the pin numbers (and the package used for the PIC). For example,
Quote:

PIC24 pin xx to ENC pin yy
.
.
.
etc.
asmallri



Joined: 12 Aug 2004
Posts: 1635
Location: Perth, Australia

View user's profile Send private message Send e-mail Visit poster's website

PostPosted: Thu Sep 14, 2017 7:40 pm     Reply with quote

pomakmrysen wrote:
Connections are ok, checked many times...


The ENC28J60 is a particularly power hungry device and a common problem I have seen supporting customers using my bootloader with this device is using a power supply that cannot supply the necessary power transients and/or insufficient power supply decoupling and bypass capacitors.
_________________
Regards, Andrew

http://www.brushelectronics.com/software
Home of Ethernet, SD card and Encrypted Serial Bootloaders for PICs!!
pomakmrysen



Joined: 14 Sep 2017
Posts: 10

View user's profile Send private message

PostPosted: Fri Sep 15, 2017 10:53 am     Reply with quote

PCM programmer wrote:
Quote:
Connections are ok, checked many times...

Check the connections between the PIC and the ENC with an ohmmeter
and post the list of connections.
Post the pin numbers (and the package used for the PIC). For example,
Quote:

PIC24 pin xx to ENC pin yy
.
.
.
etc.


PIC24FJ128GA202 28pin tssop

RB4 to ENC PIN 10 RESET
RB5 to ENC PIN 9 CS
RB6 to ENC PIN 6 SO
RB7 to ENC PIN 8 SCK
RB8 to ENC PIN 7 SI

Measured all of them 0.1 ohms

This is hardwareprofile.h

Code:

#ifndef __HARDWAREPROFILE_H__
#define __HARDWAREPROFILE_H__

#define ENC_CS_IO        LATBbits.LATB5
#define ENC_CS_TRIS      TRISBbits.TRISB5
#define ENC_SCK_TRIS     TRISBbits.TRISB7
#define ENC_SDI_TRIS     TRISBbits.TRISB8
#define ENC_SDO_TRIS     TRISBbits.TRISB6
#define ENC_RST_IO       LATBbits.LATB4
#define ENC_RST_TRIS     TRISBbits.TRISB4
#define ENC_SSPBUF       SPI1BUF
#define ENC_SPICON1      SPI1CON1L
#define ENC_SPICON1bits  SPI1CON1Lbits
#define ENC_SPISTAT      SPI1CON1L
#define ENC_SPISTATbits  SPI1CON1Lbits
#define ENC_SPICON2      SPI1CON2
#define ENC_SPI_IF       IFS0bits.SPI1IF

#pin_select SCK1OUT=PIN_B7
#pin_select SDI1=PIN_B6
#pin_select SDO1=PIN_B8

#endif
pomakmrysen



Joined: 14 Sep 2017
Posts: 10

View user's profile Send private message

PostPosted: Fri Sep 15, 2017 11:56 am     Reply with quote

I see now maybe some interrupt problem. First time freeze waiting adc interrupt flag:
Code:
while(!IFS0bits.AD1IF);


Second time waiting for spi interrupt flag:
Code:

#define ENC_SPI_IF       IFS0bits.SPI1IF
#define WaitForDataByte()   {while(!ENC_SPI_IF); ENC_SPI_IF = 0;}
pomakmrysen



Joined: 14 Sep 2017
Posts: 10

View user's profile Send private message

PostPosted: Fri Sep 15, 2017 1:23 pm     Reply with quote

Before first freeze AD1CON1 is set to 0x80E4 in library file

Code:

AD1CON1 = 0x80E4;      // Turn on the A/D module, auto-convert
   
   T1CON = 0x8000;         // TON = 1, no prescalar
   PR1 = 0xFFFF;         // Don't clear timer early
   //AD1CON1bits.SAMP = 1;
   vBitCount = 0;
   dwTotalTime = 0;
   wLastValue = 0;
   randomResult.dw = LFSRRand();
   for(;;)
   {
      ClrWdt();
      #if defined(__C30__)
         while(!IFS0bits.AD1IF);


When freeze i read it 0xC0E6 . Datasheet says bit 3 Unimplemented: Read as ‘0’ but i read it 1 ??
temtronic



Joined: 01 Jul 2010
Posts: 9246
Location: Greensville,Ontario

View user's profile Send private message

PostPosted: Fri Sep 15, 2017 1:33 pm     Reply with quote

I, for one, can't follow this thread ! 1st it's an SPI device , the ENC..., that you appear to have a problem with,,then an ADC interrupt is hanging the PIC....then something else...

You need to concentrate on ONE problem at a time, show us a SMALL,compilable program with the fault, THEN we can work on that.

The PIC 'freezing' could be as simple as no handler for the interrupt, stack space too small, miswired PCB,errors not in use rs232 options or ????
Since I don't use the 24 series PICs, I can't comment on specifics, just 'general' things that will 'freeze' a PIC.

Jay
Ttelmah



Joined: 11 Mar 2010
Posts: 19553

View user's profile Send private message

PostPosted: Fri Sep 15, 2017 2:02 pm     Reply with quote

Directly using the interrupt flag for the ADC, suggests non CCS code being ported. Possibly an incorrect register address. The test for the ADC flag in CCS is:
Code:

while(!interrupt_active(INT_ADC))
    ;


However this is also very dangerous code. Any fault with the ADC programming so it is not running, and it'll hang forever.

Since you are trying to program in CCS, use the CCS functions to setup the ADC, and read the ADC...
pomakmrysen



Joined: 14 Sep 2017
Posts: 10

View user's profile Send private message

PostPosted: Sat Sep 16, 2017 9:28 am     Reply with quote

Ttelmah wrote:
Directly using the interrupt flag for the ADC, suggests non CCS code being ported. Possibly an incorrect register address. The test for the ADC flag in CCS is:
Code:

while(!interrupt_active(INT_ADC))
    ;


However this is also very dangerous code. Any fault with the ADC programming so it is not running, and it'll hang forever.

Since you are trying to program in CCS, use the CCS functions to setup the ADC, and read the ADC...


Register address is correct. I suspect faulty pic
Ttelmah



Joined: 11 Mar 2010
Posts: 19553

View user's profile Send private message

PostPosted: Sat Sep 16, 2017 11:49 am     Reply with quote

Thing that worries me is you have the ADC set to PIA extended DMA mode, and are then trying to poll the ADC interrupt flag.

I think you have the ADC set-up incorrectly for what you are trying to do.
temtronic



Joined: 01 Jul 2010
Posts: 9246
Location: Greensville,Ontario

View user's profile Send private message

PostPosted: Sat Sep 16, 2017 4:07 pm     Reply with quote

If you're still having ADC problems, get rid of ALL other code !
A SIMPLE loop of read ADC, send raw data to PC screen, loop.

Show us THAT code, if the problem STILL continues...

Jay
pomakmrysen



Joined: 14 Sep 2017
Posts: 10

View user's profile Send private message

PostPosted: Thu Sep 28, 2017 10:14 am     Reply with quote

Hello everybody, problem was faulty pic. I also tried library with PIC18 working well. Now i try with PIC24HJ128GP202 and when try to reach web page address trap occur. I take the address of trap from interrupt routine its 0x4F1A. In list file I find the address:

Code:
.................... 
....................     for(;;)
....................     {
....................         // Bring current FAT entry into RAM.
....................       #if defined(MPFS_USE_EEPROM)
....................            XEEReadArray(FAT, (unsigned char*)&entry, sizeof(entry));
....................       #elif defined(MPFS_USE_SPI_FLASH)
....................            SPIFlashReadArray(FAT, (BYTE*)&entry, sizeof(entry));
....................       #else
....................          #if defined(__C30__)
....................               memcpypgm2ram(&entry, (ROM void*)(WORD)FAT, sizeof(entry));
04F14:  MOV     #C10,W1
04F16:  MOV     C22,W2
04F18:  REPEAT  #10
04F1A:  MOV.B   [W2++],[W1++]


and when we look instruction before this address its 04F18: REPEAT #10

Can REPEAT instruction make this trap ?
Display posts from previous:   
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion All times are GMT - 6 Hours
Goto page 1, 2  Next
Page 1 of 2

 
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