I am trying to make a fairly simple call using PICC18.
Using the MPLAB simulator I am seeing the arguments, even on entry to the function, being completely garbled.
I have the following typedef
typedef struct
{
// t_ax25AddressChar callsign[6];
unsigned char callsign[6];
union
{
struct
{
unsigned isRepeated:1; // MSB - 1=repeated
unsigned reserved:2; // Reserved
unsigned ssid:4; // SSID
unsigned isLast:1; // LSB - Is the last address
};
unsigned char value;
} flags;
} t_ax25Callsign;
(My TODO list includes working out the order I need to specify bitfields)
That is embedded in a further struct
typedef struct
{
union
{
struct
{
t_ax25Callsign to;
t_ax25Callsign from;
t_ax25Callsign path[APRS_MAX_REPEATERS];
};
t_ax25Callsign allCallsigns[APRS_MAX_REPEATERS + 2];
} address;
// PID and Control are hard coded for APRS
const char message[APRS_MAX_MESSAGE_LENGTH + 1]; // null terminated message string
} t_aprsPacket;
and allocated somewhere in paged RAM (in main.c)
#pragma udata
static t_aprsPacket s_packet;
The method defined in aprs.h
extern void aprsMakeCallsignPgm(t_ax25Callsign *buffer,
const rom char *callsign, unsigned char ssid);
(I did try putting a "far" in there following string.h's example. No effect - and on this PIC I don't have 64K so really ought to recompile everything as 'near')
The implementation in aprs.c is
void aprsMakeCallsignPgm(t_ax25Callsign *buffer,
const rom char *callsign,
unsigned char ssid)
{
int i = 0;
volatile char ch;
for(i=0; i<6 && (ch = callsign[i]) != 0; i++)
{
buffer->callsign[i] = ch << 1;
}
for( ; i<6; i++)
{
buffer->callsign[i] = (' '<<1);
}
buffer->flags.value = 0;
buffer->flags.ssid = ssid;
}
(It could be optimised. Best get this working first. This implementation lets me see what's in ch as it goes round the loop.)
A couple of calls from main() in main.c are
aprsMakeCallsignPgm(&(s_packet.address.from), "M0RJC", (unsigned char)9);
aprsMakeCallsignPgm(&(s_packet.address.to), "APRS", 0);
s_packet.address.to.flags.isLast = 1;
strcpypgm2ram(s_packet.message, "Hard coded test message");
That cast to (unsigned char) didn't help either.
The first three lines compile, but when run in the MPLAB simulator produce gibberish in the arguments in the function implementation.
The strcpy line gives a compiler warning "Warning [2066] type qualifier mismatch in assignment". It would be nice if it told me which assignment.
What have I done wrong here?
Thanks
I was calling an assembler init routine which was using FSR2, so corrupting the C stack. I changed it to use FSR0 instead and it now works.
The shorter code that does the same thing is
void aprsMakeCallsignPgm(t_ax25Callsign *buffer,
const rom char *callsign,
unsigned char ssid)
{
int i;
overlay char *dst = buffer->callsign;
for(i = 6; i && (*dst++ = (*callsign++ << 1)); i--);
dst--; // Rewind that 0. Good job flags is there to save from overrun
for( ; i ; i--) *dst++ = (' '<<1);
buffer->flags.value = (ssid & 0x0F) << 1;
}
I'm compiling in "debug" mode, so not optimising. It's useful to see how it does in this mode as I only have the evaluation version of the compiler. The new versions saves 66 program locations and 3 bytes of RAM. It also teaches me that the correct way round for bitfields is
struct
{
unsigned isLast:1; // LSB - Is the last address
unsigned ssid:4; // SSID
unsigned reserved:2; // Reserved
unsigned isRepeated:1; // MSB - 1=repeated
};
I take the << operator as not including carry.
Thanks - Richard
(I would mark this question for remove - but note it has been marked a favourite so don't want to sweep it from underneath someone's feet)