General Notes

ICDS.EXE Stand alone driver for in circuit programming of PIC ROM from hex files, Rename to .EXE after download
CCS Load New version of the ICD controller
Program Revs Revisions to the CCS PICC Compiler
+FORCE_NEW To force the compiler to open a new instance when the icon is clicked, Right click on your desktop icon and select PROPERTIES, and insert this at the end of the TARGET window (be sure to separate it with a space!)


I2C Slave

New Example Code
CCS Slave Example
Multi R/W TES Stack
Updates from CCS PICC compiler version 4.075 to 4.076 resulted in the behavior and data returned by the I2C_ISR_STATE( ) internal function changing which would break the code written in the earlier version as explained below by CCS:

"A bug was discovered in I2C_ISR_STATE() function that only showed up at certain speeds. The fix forced us to change the EX_SLAVE.C example as we had depended on the mis-behavior. Look at the new EX_SLAVE.C and you will see there is a minor change you need to make to your ISR as well.  The I2C_ISR_STATE function was reading the input buffer to find the direction of the transfer. This satisfied the need to read the incoming byte and usually another I2C_READ soon afterward would just get the byte again. The new code does not do that read, eliminating the possibility of a new byte coming in and keeping everything in sync (one I2C_READ for every partner I2C_WRITE)."

The effect of the changed compilation was that hardware running code written for the earlier compiler would lock up the I2C bus while it waited for an extra read that never came.   The example code was tested on a PIC16F677 with a hardware I2C slave.
SET_PWMx_DUTY(n); An 8 bit constant will affect only the upper 8 bits of the duty cycle register, i.e. CCPRxL while setting the lower 2 bits in the CCPxCON to 0.  When 8 and 16 bit constants are mixed in this way, 0x80 and 0x200 will both result in a 50% duty cycle (Assuming PR2 is 255) To get a 10 bit resolution when using constants put an L after the constant. For example: 


When using the result of a math function, i.e. VarX<<2, the same thing will happen depending on the resulting value.  To force a 10 bit duty cycle, cast the variable as 16 bits (This creates really ugly assembly code):

SET_PWM1_DUTY((INT16) VarX<<2);

Another way to ensure an 8 bit duty cycle is to bypass the compiler control via a direct memory write:

#byte     pwm1duty    =0xfbe    //direct pwm wr, "Compiler issues", PIC18F2520

pwm1duty = 0x80;
pwm1duty = VarX<<2;
#FUSES  XINST This totally screws up the operation of the PIC in stand-alone mode but seems to have little effect in ICD debug mode.  As of version 4.038...

CCS:  "At present the compiler does not support the XINST mode. It will probably be supported after we release the dsPIC compiler."


ICD debugging
PIC16F690-ICD and
flash programming
Target        PIC16F690 (Special ICD part)
ICD             ICDS-3V, V1.39 (PIC16)
IDE             PCWH 4.099

When selecting [Debug],[ICD Serial] the IDE behaves as follows:

Version Behavior
4.093 ++        Immediately displays programming verification errors, did not appear to attempt programming
4.091-92        Dialog pops up "Can't find new device", no attempt to program
4.090              No issue programming or debugging

The PIC16F690 family including the special -ICD parts can't be flash programmed below 4.5V.  This includes production and debugging.
ICD debugging
Can't break 1 before or 1 instruction after a while loop because the Carry/nBorrow flag in the status register (0x03.0) does not operate correctly when break points are set before where this flag is used and the code in question is stepped through.  This happened the first time when using the statement below:

.................... value=(temp1 * 11) + temp2;
0131: MOVF 4A,W
0132: MOVWF 50
0133: MOVLW 0B
0134: MOVWF 51
0159: MOVF 4B,W
015A: ADDWF 21,W
015B: MOVWF 49
.................... if (value > 119)
015C: MOVF 49,W
015D: SUBLW 77
015E: BTFSC 03.0
015F: GOTO 162
....................      value=119;
0160: MOVLW 77
0161: MOVWF 49
.................... value=(value << 1) + 16;
0162: BCF 03.0
0163: RLF 49,W

"value" was 120 when the breakpoint was set at Addr(0x131) and single stepping the code skipped past the test at Addr(0x15E) where the carry should have been 0x0 (indicating a borrow!).  Setting the breakpoint at Addr(0x162) and examining the result indicated the operation completed properly.
ICD Executive - PIC18F JT:  "I am writing code that will store a large amount of data into the program ROM of an 18F2520 and would like to leave room for the ICD monitor code.  It appears that the current version of ICD uses the space from 0x7CC0 to 0x7F0D (Byte address) for the monitor but I would imagine that the monitor block begins at 0x7C00 but just front loaded with NOPs.  Would you have any guidelines as to how much space to allocate for current and future ICD needs?"

CCS:  "It should be save to go up to 7CBF. This code does not change much.  Note that when you use ICD=TRUE the value of getenv("PROGRAM_MEMORY") will be 7CC0."
PIC16F88 can't detect When programming the PIC16F88 with the ICD and the MCLRn pin has been disabled in the fuse settings, the device may not detect properly from that moment on because of how the PIC enters programming mode.  If seems that if the PIC has been allowed to initialize, the reset pin is treated as an I/O and the internal program mode entry state machine (MCLRn=0/RB6-7=0/MCLRn=Vpp) does not function.  Erasing the part eliminates the issue (Which is hard to do at this point, unless you use a full PROM programmer) until the next time the NOMCLR fuse is set.  It does not seem to have this problem in debug mode however.
Programming verification errors on debug connection with ICD If the compiled code is larger than the available ROM size - 256 bytes, the ICD executive overwrites user code which shows up as verification errors.  From the beginning of the ICD capabilities of the PICs, the top 256 byte block has been reserved for code that pipes debug data to the ICD.
"Can't load F2Dxx"
"Can't open Port"
When updating to Version 4 (4.016 specifically so far) with a clean install, getting the older serial debuggers to function from the IDE can be tough.  For the first error when using the USB to serial converters, download the DLLs for the serial interface here and copy them into the \windows\system32 directory (Just unzip then copy!).

For the second error, the IDE defaults to the native USB ICD made by CCS, that being the port it's looking for.  Once you get this message, go to the "Debugger windows" button on the right and select the "Configure" window.  From here you can select "Serial" and everything should be good to go from there on out.
Connection diagram
FW Update to match!

Locked ICD Images
Version 1.39
CCS firmware tends to eat itself if hot plugged into a target for debugging or uploading.  The Mini-ICD was laid out so that the target connector of a good ICD can be 1:1 connected to the ICSP connector of a blank or ailing ICD for upload of code.  Once uploaded, the newly programmed ICD can be firmware updated in the usual way.   After rescuing your ICD, update the firmware to match your debug target with ICD.EXE.

Note that the hex file to the left is not necessarily the latest or nor will it necessarily match your target processor (PIC16 or PIC18).  It will however have a responsive boot loader to allow you to communicate with it through its serial port to update its firmware via the serial cable with CCS ICD.EXE!

 If any TES ICD is suspected of having corrupted firmware making it unresponsive, mail it to TES for a free reflash or reflash it yourself according to the instruction diagram.
H4 clock reverts to HS (PIC 18Fxxxx family) If during a reset or reprogramming cycle of a target CPU with the ICD the displayed clock reverts back to the HS frequency from the H4 frequency (As in 40mhz >> 10mhz with a 10mhz crystal) and cycling power resolves this till the next reset or reflash:  Look at the PGM pin (RB5 on 18F252).  Holding the PGM pin low during the reset or reflash should prevent the need to power cycle the CPU.  The CCS ICD drives the MCLR pin to 13V-GND-5V during both the reset and reflash which seems to invoke the LVP mode momentarily.

There is no statement in the data sheet or Erata for the PIC18F252 that explicitly says that the power needs to be cycled or of any sensitivity to the PGM pin when LVP is disabled.

ICD - MCLR Error checklist

MCLR Error This error occurs right after code has been uploaded to the PIC in the IDE debug mode.  Below is a list of various causes:

1.  The LVP fuse was enabled by mistake and RB3 (PGM=RB3 on 16F876, PGM=RB5 on 18F252) is floating.  This also has the effect of making the H4 clock mode only work once per power cycle, reverting to HS after a stop.
2.  Too much  loading on RB6 and RB7, such as when this pin is multi purposed for ICD programming and an I/O:  Capacitive loading can delay or distort the PICs response after programming and current loading, such as when driving an LED directly with this pin, can upset the logic thresholds of the ICD.  Keep in mind that the ICD has resistors in series with its programming output pins so be sure to isolate any external load.  Use a digital or FET buffer when used as an output or provide a means to disconnect a driving signal while debugging when the pin is used as an input.  Generally it is easier to dedicate RB6 and RB7 to in circuit debugging but when short on I/Os, a little planning ahead can prevent problems.
3.  The clock oscillator is not started because of shorts, wrong cap values etc.

4.  If turning off the "Brownout" fuse seems to make the problem go away, check for a low Vdd condition.  The clock frequency is dependent on supply voltage and the PIC will not operate reliably with a clock faster than its supply dictates.  With H4 enabled, this can also be seen as a lower than expected clock frequency reported in the status line at the bottom of the debugger dialog after uploading code; ie 29mhz instead of 40mhz with a 10mhz crystal and H4 fuse set.

5.  Be sure to power cycle the device after writing the H4 fuse for the first time if it is different than the last time the part was used.  I often use the same processor for different circuits (See QuickPIC-III) so switching from an H4 to an HS will not register till the power is cycled making the part run at a frequency the ICD is not expecting.  Even though not well documented, this fuse is read only at power up and not after a MCLR reset!

6.  A particular variation of this behavior manifests itself as a PIC circuit that loads and runs its code the first time, but produces the MCLR error when attempting to reflash after the first halt. Power cycling the circuit allows it to be run once more. If never run, it will reflash and display an active "Go" button as many times as you like.  Some versions of the ICD firmware have an issue with the first GOTO to Main() landing in a "Sensitive" address area.   Moving the GOTO address by padding the memory used before Main() can result in the problem going away.  This can be done with any code compiled before main such as functions or dummy code (My favorite is sets of 16bit for/next loops that do nothing in a function called by Main() as they suck up lots of space in incremental chunks).  ICD 1.33fw does not seem to have this issue.

Reference Data

IO/LCD Worksheets I/O pin map and LCD map for documentation and planning

Any questions or comments?
 This page last updated on August 28, 2011