|
|
View previous topic :: View next topic |
Author |
Message |
pomakmrysen
Joined: 14 Sep 2017 Posts: 10
|
PIC24 + enc28j60 freeze |
Posted: Thu Sep 14, 2017 10:40 am |
|
|
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:
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
|
|
Posted: Thu Sep 14, 2017 10:50 am |
|
|
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
|
|
Posted: Thu Sep 14, 2017 10:56 am |
|
|
Connections are ok, checked many times... |
|
|
temtronic
Joined: 01 Jul 2010 Posts: 9246 Location: Greensville,Ontario
|
|
Posted: Thu Sep 14, 2017 11:08 am |
|
|
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
|
|
Posted: Thu Sep 14, 2017 4:17 pm |
|
|
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
|
|
Posted: Thu Sep 14, 2017 7:40 pm |
|
|
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
|
|
Posted: Fri Sep 15, 2017 10:53 am |
|
|
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
|
|
Posted: Fri Sep 15, 2017 11:56 am |
|
|
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
|
|
Posted: Fri Sep 15, 2017 1:23 pm |
|
|
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
|
|
Posted: Fri Sep 15, 2017 1:33 pm |
|
|
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
|
|
Posted: Fri Sep 15, 2017 2:02 pm |
|
|
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
|
|
Posted: Sat Sep 16, 2017 9:28 am |
|
|
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
|
|
Posted: Sat Sep 16, 2017 11:49 am |
|
|
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
|
|
Posted: Sat Sep 16, 2017 4:07 pm |
|
|
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
|
|
Posted: Thu Sep 28, 2017 10:14 am |
|
|
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 ? |
|
|
|
|
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
|