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

PIC16F883 write_program_memory() does not work

 
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion
View previous topic :: View next topic  
Author Message
soundscu



Joined: 29 Jun 2007
Posts: 62
Location: Raleigh, NC

View user's profile Send private message Visit poster's website

PIC16F883 write_program_memory() does not work
PostPosted: Thu Jul 05, 2007 4:34 pm     Reply with quote

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

View user's profile Send private message

PostPosted: Thu Jul 05, 2007 5:45 pm     Reply with quote

You need to post your compiler version. All versions are different.
soundscu



Joined: 29 Jun 2007
Posts: 62
Location: Raleigh, NC

View user's profile Send private message Visit poster's website

PostPosted: Thu Jul 05, 2007 5:51 pm     Reply with quote

CCS PCM C Compiler, Version 4.042
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Thu Jul 05, 2007 6:05 pm     Reply with quote

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

View user's profile Send private message Visit poster's website

PostPosted: Thu Jul 05, 2007 6:34 pm     Reply with quote

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

View user's profile Send private message Visit poster's website

PostPosted: Thu Jul 05, 2007 7:01 pm     Reply with quote

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

View user's profile Send private message

PostPosted: Thu Jul 05, 2007 8:05 pm     Reply with quote

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

View user's profile Send private message Visit poster's website

PostPosted: Fri Jul 06, 2007 5:51 am     Reply with quote

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

View user's profile Send private message

PostPosted: Fri Jul 06, 2007 11:31 am     Reply with quote

My advice is to contact CCS support about this.
Display posts from previous:   
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion All times are GMT - 6 Hours
Page 1 of 1

 
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