|
|
View previous topic :: View next topic |
Author |
Message |
soundscu
Joined: 29 Jun 2007 Posts: 62 Location: Raleigh, NC
|
PIC16F883 write_program_memory() does not work |
Posted: Thu Jul 05, 2007 4:34 pm |
|
|
I am debugging PIC16F883 code with the CCS bootloader included and have come to the following conclusions:
1. The "write_program_memory(addr, data, count);" statement in the bootloader code does not successfully write to flash memory. I have added printf() routines to the bootloader to print three info lines: (a)program memory contents before writing, (b)the new values to be written, and (c)the contents after writing. The before and after are the same, regardless of the new values that are being written.
2. SIOW sends the first line of the hex file, then reports "timeout while downloading". I presume it's supposed to see the returned XOFF byte from the bootloader and wait, but it times out instead.
These issues could very well be an oversight on my part, but I am stumped. I sure could use some help at this point. TIA. :)
Jim |
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Thu Jul 05, 2007 5:45 pm |
|
|
You need to post your compiler version. All versions are different. |
|
|
soundscu
Joined: 29 Jun 2007 Posts: 62 Location: Raleigh, NC
|
|
Posted: Thu Jul 05, 2007 5:51 pm |
|
|
CCS PCM C Compiler, Version 4.042 |
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Thu Jul 05, 2007 6:05 pm |
|
|
Post a short test program that shows the problem.
See these threads for examples of test programs:
http://www.ccsinfo.com/forum/viewtopic.php?t=28440
http://www.ccsinfo.com/forum/viewtopic.php?t=25112
Write a program that's similar to those (in style), but make it shorter.
For example, just write to the memory and then read it back
and display it.
When you write the test program, use the write_program_memory()
function in the same way that you're doing it in your program.
Declare the variables in the same way. |
|
|
soundscu
Joined: 29 Jun 2007 Posts: 62 Location: Raleigh, NC
|
|
Posted: Thu Jul 05, 2007 6:34 pm |
|
|
Thank you for your suggestions. I've already begun making a very simple test program. :)
It's not finished yet, but I'm puzzled by the following:
When I compile this C code:
Code: | #include "D:\My Documents\Eng\Ctest\main.h"
int32 addr = 0x1000;
int8 data[8] = 1,2,3,4,5,6,7,8;
int8 count = 8;
void main()
{
setup_adc_ports(NO_ANALOGS|VSS_VDD);
setup_adc(ADC_OFF);
setup_spi(SPI_SS_DISABLED);
setup_timer_0(RTCC_INTERNAL|RTCC_DIV_1);
setup_timer_1(T1_DISABLED);
setup_timer_2(T2_DISABLED,0,1);
setup_comparator(NC_NC_NC_NC);// This device COMP currently not supported by the PICWizard
//Setup_Oscillator parameter not selected from Intr Oscillotar Config tab
// nops are markers for reading compiled code
// (they server no functional purpose)
#asm
nop
nop
nop
#endasm
write_program_memory(addr,data,count);
#asm
nop
nop
nop
#endasm
while(TRUE)
{
;
}
} |
The resulting lst file is this:
Code: | CCS PCM C Compiler, Version 4.042, 39375 05-Jul-07 20:06
Filename: D:\My Documents\Eng\Ctest\main.lst
ROM used: 147 words (4%)
Largest free fragment is 2048
RAM used: 20 (8%) at main() level
26 (11%) worst case
Stack: 1 locations
*
0000: NOP
0001: MOVLW 00
0002: MOVWF 0A
0003: GOTO 006
.................... #include "D:\My Documents\Eng\Ctest\main.h"
.................... #include <16F883.h>
.................... //////// Standard Header file for the PIC16F883 device ////////////////
.................... #device PIC16F883
.................... #list
....................
.................... #device adc=8
....................
.................... #FUSES NOWDT //No Watch Dog Timer
.................... #FUSES INTRC_IO //Internal RC Osc, no CLKOUT
.................... #FUSES PUT //Power Up Timer
.................... #FUSES MCLR //Master Clear pin enabled
.................... #FUSES NOPROTECT //Code not protected from reading
.................... #FUSES NOCPD //No EE protection
.................... #FUSES BROWNOUT //Reset when brownout detected
.................... #FUSES NOIESO //Internal External Switch Over mode disabled
.................... #FUSES FCMEN //Fail-safe clock monitor enabled
.................... #FUSES NOLVP //No low voltage prgming, B3(PIC16) or B5(PIC18) used for I/O
.................... #FUSES NODEBUG //No Debug mode for ICD
.................... #FUSES NOWRT //Program memory not write protected
.................... #FUSES BORV40 //Brownout reset at 4.0V
....................
.................... #use delay(clock=8000000)
.................... #use rs232(baud=9600,parity=N,xmit=PIN_C6,rcv=PIN_C7,bits=8)
....................
....................
....................
.................... int32 addr = 0x1000;
*
002B: BCF 03.5
002C: BCF 03.6
002D: CLRF 20
002E: MOVLW 10
002F: MOVWF 21
0030: CLRF 22
0031: CLRF 23
.................... int8 data[8] = 1,2,3,4,5,6,7,8;
0032: MOVLW 01
0033: MOVWF 24
0034: MOVLW 02
0035: MOVWF 25
0036: MOVLW 03
0037: MOVWF 26
0038: MOVLW 04
0039: MOVWF 27
003A: MOVLW 05
003B: MOVWF 28
003C: MOVLW 06
003D: MOVWF 29
003E: MOVLW 07
003F: MOVWF 2A
0040: MOVLW 08
0041: MOVWF 2B
.................... int8 count = 8;
0042: MOVWF 2C
....................
.................... void main()
.................... {
*
0004: BCF 0A.3
0005: GOTO 08E (RETURN)
0006: CLRF 04
0007: BCF 03.7
0008: MOVLW 1F
0009: ANDWF 03,F
000A: MOVLW 71
000B: BSF 03.5
000C: MOVWF 0F
000D: BSF 03.6
000E: BCF 07.3
000F: MOVLW 0C
0010: BCF 03.6
0011: MOVWF 19
0012: MOVLW A2
0013: MOVWF 18
0014: MOVLW 90
0015: BCF 03.5
0016: MOVWF 18
0017: BSF 03.5
0018: BSF 03.6
0019: MOVF 09,W
001A: ANDLW C0
001B: MOVWF 09
001C: BCF 03.6
001D: BCF 1F.4
001E: BCF 1F.5
001F: MOVLW 00
0020: BSF 03.6
0021: MOVWF 08
0022: BCF 03.5
0023: CLRF 07
0024: CLRF 08
0025: CLRF 09
0026: BSF 03.5
0027: BCF 03.6
0028: CLRF 17
0029: BSF 03.6
002A: CLRF 05
....................
.................... setup_adc_ports(NO_ANALOGS|VSS_VDD);
*
0045: BSF 03.5
0046: BSF 03.6
0047: MOVF 09,W
0048: ANDLW C0
0049: MOVWF 09
004A: BCF 03.6
004B: BCF 1F.4
004C: BCF 1F.5
004D: MOVLW 00
004E: BSF 03.6
004F: MOVWF 08
.................... setup_adc(ADC_OFF);
0050: BCF 03.5
0051: BCF 03.6
0052: BCF 1F.0
.................... setup_spi(SPI_SS_DISABLED);
*
0043: MOVLW FF
0044: MOVWF 2D
*
0053: BCF 14.5
0054: BCF 2D.5
0055: MOVF 2D,W
0056: BSF 03.5
0057: MOVWF 07
0058: BCF 03.5
0059: BSF 2D.4
005A: MOVF 2D,W
005B: BSF 03.5
005C: MOVWF 07
005D: BCF 03.5
005E: BCF 2D.3
005F: MOVF 2D,W
0060: BSF 03.5
0061: MOVWF 07
0062: MOVLW 01
0063: BCF 03.5
0064: MOVWF 14
0065: MOVLW 00
0066: BSF 03.5
0067: MOVWF 14
.................... setup_timer_0(RTCC_INTERNAL|RTCC_DIV_1);
0068: MOVF 01,W
0069: ANDLW C7
006A: IORLW 08
006B: MOVWF 01
.................... setup_timer_1(T1_DISABLED);
006C: BCF 03.5
006D: CLRF 10
.................... setup_timer_2(T2_DISABLED,0,1);
006E: MOVLW 00
006F: MOVWF 78
0070: MOVWF 12
0071: MOVLW 00
0072: BSF 03.5
0073: MOVWF 12
.................... setup_comparator(NC_NC_NC_NC);// This device COMP currently not supported by the PICWizard
0074: BCF 03.5
0075: BSF 03.6
0076: CLRF 07
0077: CLRF 08
0078: CLRF 09
0079: BSF 03.5
007A: BCF 03.6
007B: CLRF 17
007C: BSF 03.6
007D: CLRF 05
.................... //Setup_Oscillator parameter not selected from Intr Oscillotar Config tab
....................
.................... // nops are markers for reading compiled code
.................... // (they server no functional purpose)
.................... #asm
.................... nop
007E: NOP
.................... nop
007F: NOP
.................... nop
0080: NOP
.................... #endasm
....................
.................... write_program_memory(addr,data,count);
0081: BCF 03.5
0082: BCF 03.6
0083: MOVF 21,W
0084: MOVWF 2F
0085: MOVF 20,W
0086: MOVWF 2E
0087: CLRF 31
0088: MOVLW 24
0089: MOVWF 30
008A: CLRF 33
008B: MOVF 2C,W
008C: MOVWF 32
008D: GOTO 004
....................
.................... #asm
.................... nop
008E: NOP
.................... nop
008F: NOP
.................... nop
0090: NOP
.................... #endasm
....................
.................... while(TRUE)
.................... {
.................... ;
.................... }
0091: GOTO 091
....................
.................... }
0092: GOTO 092
Configuration Fuses:
Word 1: 08F4 INTRC_IO NOWDT NOPUT MCLR NOPROTECT NOCPD NOBROWNOUT NOIESO FCMEN NOLVP DEBUG
Word 2: 3FFF NOWRT BORV40 |
I have two questions:
Why is the write_program_memory routine so short? It does not seem to contain any of the necessary steps for writing to flash memory.
I've added comments to show what I think the asm code is doing:
Code: |
.................... write_program_memory(addr,data,count);
BCF 03.5 ;clear bank
BCF 03.6 ; select bits
MOVF 21,W ;copy value in 21
MOVWF 2F ; to 2F
MOVF 20,W ;copy value in 20
MOVWF 2E ; to 2E
CLRF 31 ;clear location 31
MOVLW 24
MOVWF 30 ;load 30 with literal value 24
CLRF 33 ;clear location 33
MOVF 2C,W ;copy value in 2C
MOVWF 32 ; to location 32
GOTO 004 ;jump to address 004, where PCLATH.3 is cleared,
; then the program jumps back to here...
|
Which all seems kinda useless to me. What am I missing here? Honestly, I'm feelin' kinda dumb right now. :(
Jim |
|
|
soundscu
Joined: 29 Jun 2007 Posts: 62 Location: Raleigh, NC
|
|
Posted: Thu Jul 05, 2007 7:01 pm |
|
|
Ok, I think I'm on to something.
I start with these lines of C code:
Code: | // nops are markers for reading compiled code
// (they server no functional purpose)
#asm
nop
nop
nop
#endasm
write_program_memory(addr,data,count);
#asm
nop
nop
nop
#endasm
read_program_memory(addr,data,count);
#asm
nop
nop
nop
#endasm |
When compiled in MPLAB where I can more easily look at actual program memory, I find this:
Code: | 19: // nops are markers for reading compiled code
20: // (they server no functional purpose)
21: #asm
22: nop
09B 0000 NOP
23: nop
09C 0000 NOP
24: nop
09D 0000 NOP
25: #endasm
26:
27: write_program_memory(addr,data,count);
09E 1283 BCF 0x3, 0x5
09F 1303 BCF 0x3, 0x6
0A0 0821 MOVF 0x21, W
0A1 00AF MOVWF 0x2f
0A2 0820 MOVF 0x20, W
0A3 00AE MOVWF 0x2e
0A4 01B1 CLRF 0x31
0A5 3024 MOVLW 0x24
0A6 00B0 MOVWF 0x30
0A7 01B3 CLRF 0x33
0A8 082C MOVF 0x2c, W
0A9 00B2 MOVWF 0x32
0AA 2804 GOTO 0x4
28:
29: #asm
30: nop
0AB 0000 NOP
31: nop
0AC 0000 NOP
32: nop
0AD 0000 NOP
33: #endasm
34:
35: read_program_memory(addr,data,count);
0AE 0821 MOVF 0x21, W
0AF 1703 BSF 0x3, 0x6
0B0 008F MOVWF 0xf
0B1 1303 BCF 0x3, 0x6
0B2 0820 MOVF 0x20, W
0B3 1703 BSF 0x3, 0x6
0B4 008D MOVWF 0xd
0B5 3024 MOVLW 0x24
0B6 0084 MOVWF 0x4
0B7 1383 BCF 0x3, 0x7
0B8 1303 BCF 0x3, 0x6
0B9 082C MOVF 0x2c, W
0BA 00AE MOVWF 0x2e
0BB 2806 GOTO 0x6
36:
37: #asm
38: nop
0BC 0000 NOP
39: nop
0BD 0000 NOP
40: nop
0BE 0000 NOP
41: #endasm |
The write routine jumps to this routine at addr 004:
Code: | 004 118A BCF 0xa, 0x3
005 28AB GOTO 0xab |
But the read routine jumps to this much more substantial code at addr 006:
Code: | 006 082E MOVF 0x2e, W
007 00F7 MOVWF 0x77
008 0AF7 INCF 0x77, F
009 1003 BCF 0x3, 0
00A 0CF7 RRF 0x77, F
00B 1683 BSF 0x3, 0x5
00C 1703 BSF 0x3, 0x6
00D 178C BSF 0xc, 0x7
00E 140C BSF 0xc, 0
00F 0000 NOP
010 0000 NOP
011 1283 BCF 0x3, 0x5
012 080C MOVF 0xc, W
013 0080 MOVWF 0
014 0A84 INCF 0x4, F
015 080E MOVF 0xe, W
016 0080 MOVWF 0
017 0A84 INCF 0x4, F
018 0A8D INCF 0xd, F
019 1903 BTFSC 0x3, 0x2
01A 0A8F INCF 0xf, F
01B 0BF7 DECFSZ 0x77, F
01C 281E GOTO 0x1e
01D 2820 GOTO 0x20
01E 1683 BSF 0x3, 0x5
01F 280E GOTO 0xe
020 1303 BCF 0x3, 0x6
021 118A BCF 0xa, 0x3
022 28BC GOTO 0xbc |
The read code looks appropriate. The write code appears to be... missing!
Jim |
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Thu Jul 05, 2007 8:05 pm |
|
|
A lot of your code isn't correct. It doesn't match what the data sheet
says, or what the compiler says for the 16F series chips.
For example, 0x1000 is beyond the available word address range of
the 16F883. You should write words to the 16F series, not bytes.
To see the CCS library code in the .LST file, you need to comment out
the #nolist statement at the top of the 16F883.H file.
However, given all that, and after making corrections, I agree that the
it doesn't generate any library code for the write_program_memory()
function. But then I changed the #include file to 16F887.H, which is
a related chip in same series. Then it generated the code.
This may mean that the Device Data entry for the 16F883 is incorrect.
Writing to program memory may not be enabled for this PIC, due to an
oversight in setting up the Device Data file. If you have the full IDE
(PCWH), you could look at the entry for the 16F883 and compare it to
16F887. See if there is a parameter or some setting that is disabled for
the 16F883. Then maybe you could enable it. If you don't have the
full IDE, or if that doesn't work, then contact CCS support and ask them
about it. |
|
|
soundscu
Joined: 29 Jun 2007 Posts: 62 Location: Raleigh, NC
|
|
Posted: Fri Jul 06, 2007 5:51 am |
|
|
When first creating this test program, I quickly put a 0x1000 at the top, before going back to check the datasheet. It's now changed to 0x800.
Thanks for explaining the #NOLIST directive, that's very helpful.
As noted in the datasheet (not very clearly, I might add), the 16F887 writes flash in 8 word blocks, while the 16F883 writes flash in 4 word blocks. Thus, not the same code.
This difference is correctly indicated in the CCS Device Editor, so I suspect the compiler does not properly generate code for flash access identified as "PIC16 8/32" (write 8 bytes, erase 32 bytes, i.e. write 4 words, erase 16 words). It works correctly for "PIC16 16/32".
Jim |
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Fri Jul 06, 2007 11:31 am |
|
|
My advice is to contact CCS support about this. |
|
|
|
|
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
|