Problem with .byte0 modifier in Interrupt

Discuss the Firewing language

Problem with .byte0 modifier in Interrupt

Postby jmusselman64 » Thu Mar 08, 2018 4:44 am

I need a sanity check..can someone else test this code segment?
I'v reduced it to just the parts needed to compile and show the error.

The problem I'm having is the 'CRCDATL' line in 'Case 5' of the interrupt routine.
When the .Payload.RcvdChksum variable is used without the .byte modifier, it compiles correct...Rxbyte in Case5 goes to the CRCDATL register.
When I add the '.byte' modifier to it, the CRCDATL addresses all change to 0x0980 when compiled...!

I'm compiling with Microchip 16 compiler, XC16 v1.33, although is does the same with Firewing16, target board doesn't matter.

Thanks much
Code: Select all
Device = 24FJ128GA204              // Select processor
clock = 32                       // Define system clock as Fosc/2

/****************   ENUM / STRUCTURES   *****************/       
 structure payload_t
   RcvdChksum as ushort
end structure

structure S300_t
   Payload as payload_t
end structure   

/****************   VARIABLES   *****************/                                                                                           
Dim RX1STATE as byte = 0
dim U1packet as S300_t

'****************************************************************************
'* Name    : OnRX1 (Private)                                                *
'* Purpose : Interrupt Service Routine (ISR) to receive incoming data       *
'****************************************************************************
 Interrupt OnRX1(Pic.U1RXInterrupt)

   dim RXbyte as byte = U1RXREG
   
   with U1Packet
      select case RX1STATE
     
         // Get bytes                   
         case 5
               CRCDATL.byte0 = RXbyte               ' NEED TO SEND BYTE (NOT WORD) TO CRC..
         
         // Get data checksum               
         case 6
               '.Payload.RcvdChksum = RXbyte       ' THIS WORKS
               .Payload.RcvdChksum.byte0 = RXbyte  ' THIS DOESN'T...The RXbyte above is sent to 0x0980 instead! 
      end select
   end with

End Interrupt

/****************   MAIN PROGRAM   *****************/       
sub main()
   Enable (OnRX1)
 
   // MAIN LOOP
   while (true)
   end while
   
end sub
jmusselman64
 
Posts: 24
Joined: Thu Jan 22, 2015 1:01 am

Re: Problem with .byte0 modifier in Interrupt

Postby Coccoliso » Fri Mar 09, 2018 10:05 am

Hi,

the problem is in the high part of U1Packet.. is initalized ?
You can try an Erase(U1Packet) in main program.
User avatar
Coccoliso
 
Posts: 177
Joined: Sat Sep 27, 2014 10:02 am

Re: Problem with .byte0 modifier in Interrupt

Postby Jerry Messina » Fri Mar 09, 2018 12:02 pm

You're not crazy.
This may be a bit hard to follow, but the two 'case 6' statements end up with allocating CRCDATL differently.

The first choice (working) creates a byte located at the same location as the CRCDATL SFR reg address:
Code: Select all
case 6
   .Payload.RcvdChksum = RXbyte       ' THIS WORKS

'>>>>> GENERATES THIS CODE

// alias with absolute MCU address...
asm("__U1RXREG = 0x000506;"); extern volatile WORD _U1RXREG;
asm("__M352_U08 = 0x000160;"); extern volatile BYTE _M352_U08;   '<<<<<<< THIS IS AT CRCDATL ADDRESS

// CRCDATL.byte0 = RXbyte               ' NEED TO SEND BYTE (NOT WORD) TO CRC..
_M352_U08.val = IL0_U08.val;         '<<<<<<<<< moves RXbyte to "CRCDATL"


Second choice (not working) allocates "CRCDATL" in normal RAM instead of SFR space:
Code: Select all
// alias with absolute MCU address...
asm("__U1RXREG = 0x000506;"); extern volatile WORD _U1RXREG;
' <<<<<<<<<<<<<<<<< **NOTE MISSING absolute reg addr**
'<snip>
asm("_M352_U08 = USER_RAM + 0x00016C;"); extern  volatile BYTE M352_U08;   '<<<< here's where it thinks CRCDATL is

// CRCDATL.byte0 = RXbyte               ' NEED TO SEND BYTE (NOT WORD) TO CRC..
M352_U08.val = IL0_U08.val;         '<<<<<<<<< moves RXbyte to "CRCDATL", but it's not mapped to an SFR addr


The problem seems to be with this statement:
Code: Select all
CRCDATL.byte0 = RXbyte               ' NEED TO SEND BYTE (NOT WORD) TO CRC..

It doesn't generate a reference to the real CRCDATL register. It creates some fictitious mapping (or doesn't).

I know it's not what you want (and it's not a fix, just an observation), but if you get rid of the .byte0 qualifier you get a reference to the real CRCDATL register in both cases...
Code: Select all
CRCDATL = RXbyte

// alias with absolute MCU address...
asm("__U1RXREG = 0x000506;"); extern volatile WORD _U1RXREG;
asm("__CRCDATL = 0x000160;"); extern volatile WORD _CRCDATL;

// CRCDATL = RXbyte               ' NEED TO SEND BYTE (NOT WORD) TO CRC..
_CRCDATL.val = IL0_U08.val;
Jerry Messina
 
Posts: 280
Joined: Thu Feb 14, 2013 10:16 am

Re: Problem with .byte0 modifier in Interrupt

Postby jmusselman64 » Fri Mar 09, 2018 1:43 pm

Thanks, Jerry and Coccoliso for your replies. Your observations match what I found yesterday after dissecting the code in MPLAB.

Some more info for you...it gets stranger....

If I swap around the order of CASE statements so that the last statement before END SELECT includes the line 'CRCDATL.byte0 = RXbyte', then everything works.!

I don't understand why this would make a difference...seems like a bug to me.

I'm now in the process of converting this to an EVENT,...maybe it will like that better.
jmusselman64
 
Posts: 24
Joined: Thu Jan 22, 2015 1:01 am


Return to Language

Who is online

Users browsing this forum: No registered users and 2 guests

cron

x