|
|
View previous topic :: View next topic |
Author |
Message |
RckRllRfg
Joined: 20 Jul 2011 Posts: 60
|
Make16 difficulties in the loader.c file |
Posted: Thu Aug 25, 2011 1:22 am |
|
|
Hi everyone -
I at a show stopping point for my project. I am using the bootloader code provided by CCS. I have made the adjustments to the ORGs as so eloquently described by PCM programmer. But, when I try to run the code, I am getting a but of a stomp job. It took me a while to determine this; however, I have pinpointed it to the make16 command.
In my last run, the address in the hex code was 1000. l_addr was declaring it to be 0000. That run didn't go very far since the loader program starts at address 40...
I wrote a very simple code to test the make16 and to understand it better. I think I duplicated the issue. Here's are the results from my fprintfs:
Code: |
atoi1: 0x0001
atoi2: 0x0023
laddr2 with atoi1 and 2: 0x0023
laddr3 using basic C: 0x0023
LONG laddr4 using basic C: 0x0023
|
Loader.c has been around for a while, so I know that it works.
Here's my theory - I am using a PIC16. This would be an 8 bit memory. I'm trying to biuld an 16 bit word. When I look at the .lst file, I simply see the make16 putting each byte one after the other. For example:
Code: |
................. l_addr2 = make16(atoi1,atoi2);
09C2: MOVF 2B,W
09C3: MOVWF 28
09C4: MOVF 2C,W
09C5: MOVWF 27
|
So, am I dealing with a paging issue? ie, is the location of the of memory outside of my address range?
I will post the "simple" code and the bootloader.h which will be needed to compile and run. I have modified it to give me ample memory for the real_load_program to include PRINTF statements.
Using Version V4.123
Using a PIC16F1947 (but don't let that scare ya since a fool like me has made it dance and sing...I just need to give it a boot!)
RckRllRfg |
|
|
RckRllRfg
Joined: 20 Jul 2011 Posts: 60
|
The code .... |
Posted: Thu Aug 25, 2011 1:30 am |
|
|
Code: |
#include <16F1947.h>
#fuses HS,NOWDT,NOPROTECT,NOLVP
#use delay(clock=16000000)
#use rs232( UART2, baud=9600, parity=N, xmit=PIN_G1, rcv=PIN_G2, bits=8, stream=sourceside)
#include <bootloader.h>
int i=0;
char buffer[4];
int16 l_addr1, l_addr2, l_addr3;
int8 atoi1,atoi2;
long l_addr4;
unsigned int atoi_b16(char *s) { // Convert two hex characters to a int8
unsigned int result = 0;
int i;
for (i=0; i<2; i++,s++) {
if (*s >= 'A')
result = 16*result + (*s) - 'A' + 10;
else
result = 16*result + (*s) - '0';
}
return(result);
}
void main(void) {
//Activate the Transciever (OUT-ON)
output_high(PIN_E5);
// Establish protocol mode on Pin RE6: RS-485 is high
output_high(PIN_E6);
//// Enable TX mode (DXEN)
output_high(PIN_E7);
//// Disable RX mode (RXEN)
output_low(PIN_E4);
setup_oscillator(OSC_16MHZ);
buffer[0] = '0';
buffer[1] = '1';
buffer[2] = '2';
buffer[3] = '3';
atoi1 = atoi_b16(&buffer[0]);
atoi2 = atoi_b16(&buffer[2]);
fprintf(sourceside,"atoi1: 0x%4x \r\n", atoi1);
fprintf(sourceside,"atoi2: 0x%4x \r\n", atoi2);
l_addr1 = make16(atoi_b16(&buffer[0]),atoi_b16(&buffer[2]));
fprintf(sourceside,"laddr1: 0x%4x \r\n", l_addr1);
l_addr2 = make16(atoi1,atoi2);
fprintf(sourceside,"laddr2 with atoi1 and 2: 0x%4x \r\n", l_addr2);
l_addr3 = atoi2 | (atoi1 <<8);
fprintf(sourceside,"laddr3 using basic C: 0x%4x \r\n", l_addr3);
l_addr4 = atoi2 | (atoi1 <<8);
fprintf(sourceside,"LONG laddr4 using basic C: 0x%4x \r\n", l_addr4);
}
|
NOTES:
You can remove my Transceiver stuff. I am using a half duplex RS485 and I need to control the direction.
I am using the internal 16M oscillator, so change the delay if using a different speed and remove the ocsillator declaration.
I am using UART2. Make sure the rs232 command is set accordingly for UART 1 |
|
|
RckRllRfg
Joined: 20 Jul 2011 Posts: 60
|
bootloader.h |
Posted: Thu Aug 25, 2011 1:34 am |
|
|
Code: |
// for now, give me a ton of memory
// LOADER_END at 0x1FF + 0x600 = 7FF
#define LOADER_END (0x1FF + 0x600 )
#define LOADER_SIZE (0x1BF + 0x600 )
#ifndef _bootloader
// With LOADER_END at 0x1FF + 0x600 = 7FF
// reset
#build(reset=LOADER_END+1, interrupt=LOADER_END+5)
#org 0, LOADER_END {}
#endif
|
Notes:
I remove the PCH stuff to thin out the code
I added as much memory for the loader that I could get away with. I'll thin it out later; however, the 1947 has a ton of memory, so I'm not worried about keeping the code tight at this point. |
|
|
RF_Developer
Joined: 07 Feb 2011 Posts: 839
|
|
Posted: Thu Aug 25, 2011 5:35 am |
|
|
Two wrongs don't make a right... nor do they imply a well used and well proven CCS function is wrong.
There's nothing wrong with make16(). However there are two problems with your code.
The format specified 'x' formats an int, i.e. 8 bits only. Even if you give it an int32, or even an int32 it will only format and print the lowest two hex digits. To get int16s to format in hex you need 'Lx'. You might be thinking that 'x' formats an int, and so it does, but in CCS int is just 8 bits.
The other problem is all about casting. I've been writing recently on another thread about this. l_addr3 = atoi2 | (atoi1 <<8); wont do what I think you are expecting. atoi1 and atoi2 are int8s, and the literal '8' will fit into an int8 therefore the expression atoi2 | (atoi1 <<8) will be evaluated in int8 arithmetic. That means you will loose all of atoi1 as it will get shifted out of an int8. What you need is l_addr3 = atoi2 | ((int16)atoi1 <<8); which forces the whole expression to be computed in int16 form. It doesn't matter anyway as your format specifier, 'x', will ignore the top byte of any int16.
RF Developer |
|
|
RckRllRfg
Joined: 20 Jul 2011 Posts: 60
|
Recommendations worked...but, where's lies the problem? |
Posted: Thu Aug 25, 2011 7:19 am |
|
|
RF Developer -
Thank you for your insights and recommendations. Upon implimenting them in the sample code, I was able to see the 16 bit values.
With that being said... I'm going to have to start digging around again. I know that I have a stomp job going on . At this point, the "disintegration" of the loader program is repeatable.
I need to think about this and look further into it. But, any recommendations would be appreciated.
RckRllRfg |
|
|
|
|
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
|