|
|
View previous topic :: View next topic |
Author |
Message |
TopLoser Guest
|
|
Posted: Thu Apr 30, 2009 3:41 pm |
|
|
The board is a very small custom designed double sided board with ground planes and very carefully laid out power. The power supply is very well designed (it's derived from a nominal 24v supply via a pre-regulator and then a 5v regulator). It's the very small square surface mount version of the 16F677 and has adequate decoupling. The board is professionally designed by a very large company and will be produced in large volumes in a commercial product - I'm not at liberty to say much more.
The company involved in the design use tens of thousands of PICs and have very good support directly from Microchip - but I'm now treating this as a potential compiler issue. I've reported it to CCS directly but have had no reply hence I've taken it onto this forum.
I myself have been writing embedded C code (and designing embedded systems and laying out boards) for over 25 years and have stumbled across all sorts of hardware and software related bugs.
I suppose I should start looking at the LST files next and trying to decipher that horrible assembly code that PICs use.
In fact - here's the code generated for the read_eeprom version
Code: |
int8 c;
c = read_eeprom(1);
3001 MOVLW 0x1
1703 BSF 0x3, 0x6
008D MOVWF 0xd
080C MOVF 0xc, W
1303 BCF 0x3, 0x6
00A6 MOVWF 0x26
|
and the direct to registers version
Code: |
#BYTE EEADR = 0x10d
#byte EEDAT = 0x10c
#BYTE EECON1 = 0x18c
#BIT EEPGD = 0x18c.7
#BIT RD = 0x18c.0
EEADR=1;
3001 MOVLW 0x1
1703 BSF 0x3, 0x6
008D MOVWF 0xd
EEPGD=0;
1683 BSF 0x3, 0x5
138C BCF 0xc, 0x7
RD=1;
140C BSF 0xc, 0
c=EEDAT;
1283 BCF 0x3, 0x5
080C MOVF 0xc, W
1303 BCF 0x3, 0x6
00A6 MOVWF 0x26
|
If anybody knows enough about PIC assembler to explain the differences I'd be grateful. |
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Thu Apr 30, 2009 4:08 pm |
|
|
Your code:
Quote: | int8 c;
c = read_eeprom(1);
3001 MOVLW 0x1
1703 BSF 0x3, 0x6
008D MOVWF 0xd
080C MOVF 0xc, W
1303 BCF 0x3, 0x6
00A6 MOVWF 0x26 |
This is the ASM code that I get in the .LST file with vs. 4.085:
Code: | .................... c = read_eeprom(1);
001E: MOVLW 01
001F: BSF 03.6
0020: MOVWF 0D
0021: BSF 03.5
0022: BCF 0C.7
0023: BSF 0C.0
0024: BCF 03.5
0025: MOVF 0C,W
0026: BCF 03.6
0027: MOVWF 26 |
Here is the same thing, but in symbolic format:
Code: |
.................... c = read_eeprom(1);
001E: MOVLW 01
001F: BSF STATUS.RP1
0020: MOVWF EEADR
0021: BSF STATUS.RP0
0022: BCF EECON1.EEPGD
0023: BSF EECON1.RD
0024: BCF STATUS.RP0
0025: MOVF EEDAT,W
0026: BCF STATUS.RP1
0027: MOVWF c |
I notice that your list file uses commas in the BSF statements.
I was not able to duplicate that with any list file mode setting for
the CCS compiler. Are you even using the CCS compiler ? |
|
|
TopLoser Guest
|
|
Posted: Thu Apr 30, 2009 4:22 pm |
|
|
Yes I'm using CCS 4.085. I edited it slightly to remove what i thought was excess information.
actual LST file (as seen using "View, Disassembly listing" is
Code: |
44: c = read_eeprom(1);
0E2 3001 MOVLW 0x1
0E3 1703 BSF 0x3, 0x6
0E4 008D MOVWF 0xd
0E5 080C MOVF 0xc, W
0E6 1303 BCF 0x3, 0x6
0E7 00A6 MOVWF 0x26
45:
46: EEADR=1;
0E8 3001 MOVLW 0x1
0E9 1703 BSF 0x3, 0x6
0EA 008D MOVWF 0xd
47: EEPGD=0;
0EB 1683 BSF 0x3, 0x5
0EC 138C BCF 0xc, 0x7
48: RD=1;
0ED 140C BSF 0xc, 0
49: c=EEDAT;
0EE 1283 BCF 0x3, 0x5
0EF 080C MOVF 0xc, W
0F0 1303 BCF 0x3, 0x6
0F1 00A6 MOVWF 0x26
|
The format still isn't the same as yours, nor is the sequence of instructions generated by read_eeprom. I wish I knew why. |
|
|
TopLoser Guest
|
|
Posted: Thu Apr 30, 2009 4:35 pm |
|
|
Ok, just to make sure I've missed nothing out here is the full program and full assembler listing that I get. MPLAB IDE 8.20a, CCS PCM 4.085
Code: |
#include <16F677.H>
#fuses INTRC_IO , NOWDT , NOBROWNOUT, NOMCLR, NOCPD
#use delay(clock=4000000)
#BYTE EEADR = 0x10d
#byte EEDAT = 0x10c
#BYTE EECON1 = 0x18c
#BIT EEPGD = 0x18c.7
#BIT RD = 0x18c.0
void main()
{
int8 c;
c = read_eeprom(1);
EEADR=1;
EEPGD=0;
RD=1;
c=EEDAT;
while(1);
}
|
Code: |
1: #include <16F677.H>
000 3000 MOVLW 0
001 008A MOVWF 0xa
002 2804 GOTO 0x4
003 0000 NOP
2:
3: #fuses INTRC_IO , NOWDT , NOBROWNOUT, NOMCLR, NOCPD
4: #use delay(clock=4000000)
5:
6: #BYTE EEADR = 0x10d
7: #byte EEDAT = 0x10c
8: #BYTE EECON1 = 0x18c
9:
10: #BIT EEPGD = 0x18c.7
11: #BIT RD = 0x18c.0
12:
13: void main()
14: {
004 0184 CLRF 0x4
005 301F MOVLW 0x1f
006 0583 ANDWF 0x3, F
007 3061 MOVLW 0x61
008 1683 BSF 0x3, 0x5
009 008F MOVWF 0xf
00A 080F MOVF 0xf, W
00B 1283 BCF 0x3, 0x5
00C 1703 BSF 0x3, 0x6
00D 101F BCF 0x1f, 0
00E 109F BCF 0x1f, 0x1
00F 111F BCF 0x1f, 0x2
010 119F BCF 0x1f, 0x3
011 1303 BCF 0x3, 0x6
012 131F BCF 0x1f, 0x6
013 3000 MOVLW 0
014 1703 BSF 0x3, 0x6
015 009E MOVWF 0x1e
016 0199 CLRF 0x19
017 019A CLRF 0x1a
018 1683 BSF 0x3, 0x5
019 019E CLRF 0x1e
01A 1283 BCF 0x3, 0x5
01B 019B CLRF 0x1b
01C 1303 BCF 0x3, 0x6
01D 128D BCF 0xd, 0x5
15: int8 c;
16:
17: c = read_eeprom(1);
01E 3001 MOVLW 0x1
01F 1703 BSF 0x3, 0x6
020 008D MOVWF 0xd
021 080C MOVF 0xc, W
022 1303 BCF 0x3, 0x6
023 00A6 MOVWF 0x26
18:
19: EEADR=1;
024 3001 MOVLW 0x1
025 1703 BSF 0x3, 0x6
026 008D MOVWF 0xd
20: EEPGD=0;
027 1683 BSF 0x3, 0x5
028 138C BCF 0xc, 0x7
21: RD=1;
029 140C BSF 0xc, 0
22: c=EEDAT;
02A 1283 BCF 0x3, 0x5
02B 080C MOVF 0xc, W
02C 1303 BCF 0x3, 0x6
02D 00A6 MOVWF 0x26
23:
24: while(1);
02E 282E GOTO 0x2e
02F 0063 SLEEP
|
Your assembler output for the read_eeprom function matches exactly my direct to register code, and will work just fine (as you've observed before). Unfortunately my compiler forgets to generate quite a few lines when it creates the code for read_eeprom.
I'm losing a lot of confidence at the moment. |
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Thu Apr 30, 2009 4:40 pm |
|
|
Re-install the compiler. |
|
|
TopLoser Guest
|
|
Posted: Thu Apr 30, 2009 4:49 pm |
|
|
Ok, but CCS don't have historical version downloads available so I'll have to dig out backups to do that. I can't use the only version currently available for download (4.092) because that seems to be unable to deal with multiple compilation units in the same way all previous versions have.
Thank you for your patience and assistance so far. |
|
|
Guest
|
EE read problems |
Posted: Mon May 04, 2009 3:14 pm |
|
|
I have also have a similar problem reading internal EE in some 18F252 parts.
After programming, my PIC can't READ values from its internal EE, it looks just as if the EE is empty.
I can fix it if I do a READ of the EE locations using the PICkit2 after programming it. When I do this I can see that the EE did infact contain the values I expected, so I know it is being programmed correctly.
After doing this READ the application can then read the EE and it works fine from then on. It almost seems as if the programmer leaves the EE locked in some way and by performing this seperate READ with the PICstart, it unlocks it and kicks it back to life?
It does seem to vary from device to device because I first saw this some time ago and just thought I had a duff chip so I binned it. Things seemed fine for ages but now I've just come across a batch of 3 chips with this problem. Powering OFF/On does no good, but reading the EE with PICstart2 does fix them.
Any thoughts?
Thanks |
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
|
Guest
|
18F252 EE problem |
Posted: Mon May 11, 2009 5:43 pm |
|
|
I have run this code in three different devices. In all 3 have problems reading the EE once programmed:
Dev#1 date code 0841
Dev#2 date code 0904
Dev#3 date code 0614
Device #1 and #2 both read 00 for all locations until you do a READ of the EE area using the pickit2 after this they will correctly read their EE contents. However once powered OFF they revert to not working until their EEs are READ again.
This is a new behaviour. Previously once they were working they stayed working even after power OFF/ON
Dev#3 reads 00 from all locations even after MCLRs are performed. Once you power OFF/ON it works fine, and will continue to work fine from then on. No READ of the EE with the PICkit 2 is required.
Here's the cut down code
Best regards
Rob
Code: | #include <C:\program files\picc\devices\18F252.h>
#device adc=8
#use delay(clock=4000000)
#fuses XT,PUT,BROWNOUT,NOWDT,NOLVP,WDT128,NOPROTECT,BORV45
#use
RS232(Baud=9600,Xmit=PIN_C6,rcv=PIN_C7,PARITY=N,BITS=8,RESTART_WDT,ERRORS) //ERRORS will clear any
#BYTE EEADR = 0xFA9 //holds addr of ee locn
#BYTE EEDATA = 0xFA8 //holds data for ee
#BYTE EECON1 = 0xFA6 //ee access control reg
#BYTE EECON2 = 0xFA7 //send codes to this reg to unlock ee
#ROM INT 0xF00000={'T'}
#ROM INT 0xF00001={'E'}
#ROM INT 0xF00002={'S'}
#ROM INT 0xF00003={'T'}
#ROM INT 0xF00004={0x00}
#ROM INT 0xF00005={0x01}
#ROM INT 0xF00006={0x02}
#ROM INT 0xF00007={0x03}
#ROM INT 0xF00008={0x04}
#ROM INT 0xF00009={0x05}
#ROM INT 0xF0000A={0x06}
#ROM INT 0xF0000B={0x07}
#ROM INT 0xF0000C={0x08}
#ROM INT 0xF0000D={0x09}
#ROM INT 0xF0000E={0xAA}
#ROM INT 0xF0000F={0x55}
void main(void);
void read_ee();
void main(void)
{
printf("\n\rContents of EE");
read_ee();
}
void read_ee()
{
int line_counter,i,ee_address,start_addr,stop_addr;
int ee_rd_data;
start_addr=0x00;
stop_addr=0x3F;
line_counter=0;
for(i=start_addr;i<=stop_addr;i++)
{
ee_address=i;
EEADR=i; //setup next ee address
bit_clear(EECON1,7); //select ee data memory
bit_set(EECON1,0); //initiate ee read
ee_rd_data=EEDATA; //fetch ee data
if(line_counter==0)
{
printf("\r\n%X :",ee_address);
line_counter=16;
}
line_counter--;
printf("%X",ee_rd_data);
}
} |
|
|
|
Guest
|
18F252 EE problem |
Posted: Mon May 11, 2009 5:47 pm |
|
|
Sorry I forgot to say that my compiler version is 3.242
Rob |
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Tue May 12, 2009 1:43 pm |
|
|
I was able to duplicate your problem. It's happening because you're not
setting up the CFGS bit in the EECON1 register. That bit controls whether
the Config register or the data eeprom/flash memory is accessed. It's
not initialized to anything upon power-up, according to the data sheet.
I added a line to your code to do this, and then it started working.
Quote: | EEADR=i; //setup next ee address
bit_clear(EECON1,6); // *** ADDED ***
bit_clear(EECON1,7); //select ee data memory
bit_set(EECON1,0); //initiate ee read
ee_rd_data=EEDATA; //fetch ee data |
Question: The CCS read_eeprom() function already does it correctly.
It has that line in it. Why not just use the CCS built-in function ? |
|
|
Guest
|
EE problems |
Posted: Sun May 17, 2009 5:13 pm |
|
|
Thanks very much thats it!
Cant remember why I didnt use the in-built routines as that bit was written some time ago. Will use them from now.
Thanks again
Rob |
|
|
|
|
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
|