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

const int16 array low byte only with TinyBLD

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



Joined: 25 Jul 2006
Posts: 6

View user's profile Send private message

const int16 array low byte only with TinyBLD
PostPosted: Tue Jul 25, 2006 4:18 pm     Reply with quote

My system is: 18F4620, 20 MHz, CCS PCWH 3.249.

I've been working on it for some time, and I just started to add in the bootloader. I searched around and tried the TinyBLD bootloader, and it seemed to work very easily right away. However, my program does not operate properly when loaded using the bootloader. It looks like the main problem is that reads from a const int16 array only return the low byte.

Here are bits of my code along with the output:

Code:
//##### Somewhere in a .h file #####//
enum {      /* CR_ */
    CR_IDLE = 0,
    CR_ACTIVE,
    CR_IGNITER1,
    CR_IGNITER2,
    CR_CONVECTIONFAN,
    CR_AIRCOMPRESSOR,
    CR_EXHAUSTFAN,
    CR_SPARE,
    CR_PLATEMOTOR,
    CR_FEEDMOTOR,
    CR_LASTONE
};

/* In units of mA */
int16 const CR_LOW[10] = {0, 0, 300, 300, 250, 250, 800, 0, 1500, 500};
int16 const CR_HIGH[10] = {0, 0, 5000, 5000, 750, 750, 1600, 0, 3000, 1500};


//##### In a support file #####//
char IsCurrentWithinRange(char device) {
printf("device %d\r\n", device);
printf("test %ld\r\n", 5000);
printf("CR_LOW %ld\r\n", CR_LOW[device]);
printf("CR_HIGH %ld\r\n", CR_HIGH[device]);
printf("CurrentReading %ld\r\n", CurrentReading[device].int16_data);

    if(CurrentReading[device].int16_data < CR_LOW[device]) {
        return(0);
    }
    if(CurrentReading[device].int16_data > CR_HIGH[device]) {
        return(0);
    }
    return(1);
}


//##### In main() #####//
if(!IsCurrentWithinRange(CR_IGNITER1)) {
    IGN_FAIL = 1;
}
if(!IsCurrentWithinRange(CR_IGNITER2)) {
    IGN_FAIL = 1;
}


//##### The output of my program #####//
device 2
test 5000
CR_LOW 44       /* Should be 300 */
CR_HIGH 136     /* Should be 5000 */
CurrentReading 493
device 3
test 5000
CR_LOW 44       /* Should be 300 */
CR_HIGH 136     /* Should be 5000 */
CurrentReading 506


The current readings of 493 mA and 506 mA are correct, and it falls within the 300 mA to 5000 mA test range. However, the int16 const values they are compared to are truncated to the low 8 bits. Mathematically it is 44 = 300 - 256, and 136 = 5000 - (19 * 256). I will proceed to look at disassembly and hex files.
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Tue Jul 25, 2006 4:35 pm     Reply with quote

Can you provide a test program instead of code fragments ?
Post something that I can drop right into MPLAB and punch the
compile button, and it will compile. Then I can look at the .LST
file and see what's happening. Make sure the program is very
small -- no more code than what you've already posted.
peter_dufault



Joined: 25 Jul 2006
Posts: 6

View user's profile Send private message

PostPosted: Wed Jul 26, 2006 12:59 am     Reply with quote

I put together an example that I expected would illustrate the problem, except that the test functioned as I wanted the original program to! Very disappointing.

I then spent the next 10 hours taking apart the program to see if the problem would be exposed in some other way. I don't have a clean example yet, but I can make it work or not work by enabling or disabling small sections of code.

At this time it seems like the problem is sensitive to other accesses to 16 bit variables. Additionally, there may be a sensitivity to the presense of interrupt handlers, even if the contents of them are empty. There also seems to be something going on with the configuration fuses.

I will continue to work on an example as compact as possible to exercise this problem. It's 2:00 am. I will get back to this in the morning.
Ttelmah
Guest







PostPosted: Wed Jul 26, 2006 2:56 am     Reply with quote

An 'empty' interrupt handler, can be a killer. Always put a 'dummy' function (like 'delay_cycles(1)'), into such a handler if declared. When you 'call' the interrupt handler, the compiler adds the code to clear the interrupt at the end of the handler. If there is no code at all in the handler, this can get missed...

Best Wishes
peter_dufault



Joined: 25 Jul 2006
Posts: 6

View user's profile Send private message

PostPosted: Wed Jul 26, 2006 6:52 pm     Reply with quote

Well, I may have tracked down the problem. Eventually I got to where I would turn the problem on or off depending on how much code I commented out. It didn't really matter which code was removed. I wondered if there was a fuse issue. I had seen this thread: http://www.ccsinfo.com/forum/viewtopic.php?t=26242

which gave a clue about the EBTRB control bit in CONFIG7. It is the "Boot Block Table Read Protection bit" for 0x0 to 0x7FF. Note that it is active low to enable protection. In looking to how the fuses were set by the bootloader:

Code:
Fuse   Settings from the bootloader
02   __CONFIG _CONFIG1H, _OSC_HS_1H & _FCMEN_OFF_1H & _IESO_OFF_1H
19   __CONFIG _CONFIG2L, _PWRT_OFF_2L & _BOREN_OFF_2L
00   __CONFIG _CONFIG2H, _WDT_OFF_2H & _WDTPS_1_2H
84   __CONFIG _CONFIG3H, _MCLRE_ON_3H & _PBADEN_OFF_3H & _CCP2MX_PORTBE_3H
80   __CONFIG _CONFIG4L, _DEBUG_OFF_4L & _LVP_OFF_4L & _STVREN_OFF_4L & _XINST_OFF_4L
0F   __CONFIG _CONFIG5L, _CP0_OFF_5L & _CP1_OFF_5L & _CP2_OFF_5L
C0   __CONFIG _CONFIG5H, _CPB_OFF_5H
0F   __CONFIG _CONFIG6L, _WRT0_OFF_6L & _WRT1_OFF_6L & _WRT2_OFF_6L
E0   __CONFIG _CONFIG6H, _WRTB_OFF_6H & _WRTC_OFF_6H
0F   __CONFIG _CONFIG7L, _EBTR0_OFF_7L & _EBTR1_OFF_7L & _EBTR2_OFF_7L
00   __CONFIG _CONFIG7H, _EBTRB_OFF_7H & _DEVID1 & _IDLOC0

It seems to imply that the block is set to no protection. However, the actual fuse data read back into PICKit says that it is set to protection mode. I then set it to _EBTRB_ON_7H. While it assembled, the result was the same. After staring at it for a while I realized that the DEVID1 and IDLOC0 constants don't belong in CONFIG7H at all. Here are the constants of interest:

Code:
_CONFIG7H              EQU  H'30000D'
_EBTRB_ON_7H           EQU  H'BF'    ; Enabled
_EBTRB_OFF_7H          EQU  H'FF'    ; Disabled
_DEVID1                EQU  H'3FFFFE'
_IDLOC0                EQU  H'200000'

So after some rework:

Code:
Fuse   Settings from the bootloader
02   __CONFIG _CONFIG1H, _OSC_HS_1H & _FCMEN_OFF_1H & _IESO_OFF_1H
19   __CONFIG _CONFIG2L, _PWRT_OFF_2L & _BOREN_OFF_2L
00   __CONFIG _CONFIG2H, _WDT_OFF_2H & _WDTPS_1_2H
84   __CONFIG _CONFIG3H, _MCLRE_ON_3H & _PBADEN_OFF_3H & _CCP2MX_PORTBE_3H
80   __CONFIG _CONFIG4L, _DEBUG_OFF_4L & _LVP_OFF_4L & _STVREN_OFF_4L & _XINST_OFF_4L
0F   __CONFIG _CONFIG5L, _CP0_OFF_5L & _CP1_OFF_5L & _CP2_OFF_5L
C0   __CONFIG _CONFIG5H, _CPB_OFF_5H
0F   __CONFIG _CONFIG6L, _WRT0_OFF_6L & _WRT1_OFF_6L & _WRT2_OFF_6L
E0   __CONFIG _CONFIG6H, _WRTB_OFF_6H & _WRTC_OFF_6H
0F   __CONFIG _CONFIG7L, _EBTR0_OFF_7L & _EBTR1_OFF_7L & _EBTR2_OFF_7L
40   __CONFIG _CONFIG7H, _EBTRB_OFF_7H      ; *** Fixed here ***
   ;_DEVID1 & _IDLOC0                       ; *** Fixed here ***

It seems to work! In some of my tests, the transition between working and not working, even when I padded it with NOPs, produced outputs that had many changes spread throughout the code. I don't know PIC assembly well enough to interpret what was going on, but it looked like code had moved across the protected boundary that made some accesses work while others did not. I will alert the author of the TinyBLD bootloader about this issue (which only seems to effect the 18F2620 and 18F4620 bootloaders). Otherwise, it seems to work very well.
Gabriel Caffese



Joined: 09 Oct 2003
Posts: 39
Location: LA PLATA, ARGENTINA

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

PostPosted: Sun Jul 30, 2006 8:57 pm     Reply with quote

Peter_dufault,

Tinybootloader doesn´t allow you to change fuses !!
You set them once, when programming Tinybootloader in 18F4620.
If you read the PIC fuses after updating code with the bootloader, you´ll see they are just the same that when programmed the PIC with the Tinybootloader, no matter what your code says.
Even with this, it´s the best one I´ve seen.

Gabriel.-
peter_dufault



Joined: 25 Jul 2006
Posts: 6

View user's profile Send private message

PostPosted: Tue Aug 01, 2006 5:08 am     Reply with quote

Gabriel,

Yes, actually, my post was unclear. The code I listed on July 26 was from the TinyBLD source for the 18F2620 (also used for the 18F4620). The error I found was with the original source: somehow, the _DEVID1 and _IDLOC0 fuses got included in there.
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