This discussion has been locked.
You can no longer post new replies to this discussion. If you have a question you can start a new discussion

Idiocy or Idiosyncrasy

I have a problem which I have fixed, but don't know what I have done
has fixed it. As ever with these things there is a 99% chance that it
is something stupid that I'm doing.

The problem relates to a C165 processor linked to an SAE81C90 CAN
chip (but I suspect that the expert will not need any CAN familiarity
to follow this problem).

In this can chip there are two 8 bit registers which the user must set
individual bits high within to cause certain of 16 CAN messages to be
transmitted. These registers can only be set (the CAN chip
automatically unsets them when the message is successfully sent,
alternatively, another pair of registers can be written to unset the
transmit request bits). The registers are defined as:-

#define TransmitA  (*((volatile unsigned char far*)0x200008))
#define TransmitB  (*((volatile unsigned char far*)0x200009))

In my code, if I use the lines:-

TransmitB|=0xff;
TransmitA|=0xc0;
.
.
.
if ((TransmitA!=0)||(TransmitB!=0))
   {
   //set lower LED red to indicate failed transmission
   LED2A = 0;
   LED2B = 1;
   fail=yes;
   }
else
   {
   //sucessful transmission
   //set lower LED green to indicate successful transmission
   LED2A = 1;
   LED2B = 0;
   }   

...then the contents of the register TransmitA becomes scrambled -
such that bits 0 to 5 become set; and the CAN chip performs some
undefined actions (such as sending out non-existant messages, and
turning the CAN bus off).

If I instead use:-

unsigned int temp_a;
unsigned int temp_b;
.
.
.
TransmitB=0xff;
TransmitA=0xc0;
.
.
.
temp_a=TransmitA;
temp_b=TransmitB;
if ((temp_a!=0)||(temp_b!=0))
   {
   //set lower LED red to indicate failed transmission
   LED2A = 0;
   LED2B = 1;
   fail=yes;
   }
else
   {
   //sucessful transmission
   //set lower LED green to indicate successful transmission
   LED2A = 1;
   LED2B = 0;
   }   

...then all behaves itself.

My suspicion here is that there may be some rules about not using
such far volatile addresses in mathematical expressions - if so could
someone advise me what these are.

Interestingly enough - I have three slight vaiants of the same circuit
Some with German SAE81C90 chips, some with Taiwan SAE81C90
chips; some with 82C250 bus transceiver, and some with the 82C251
variant. They all behave slightly differently, one particular combination
does not mind which code is used, one produces slight message errors,
and one causes the CAN bus to shut down. Slightly puzzling, as it would
suggest a hardware problem, not the software fix which seems to have
cured the problem.


Yours (grateful in advance for any help or thoughts),


Richard Roebuck.

Parents
  • Just a wild guess: in the first version of the code the compiler could have optimized external bus access and combined the two byte reads into one word read. This could result in unexpected behaviour. But most probably I'm wrong.
    Actually, the configuration of external bus and, most importantly, the actual generated code could help a lot in the investigation.
    Regards,
    Mike

Reply
  • Just a wild guess: in the first version of the code the compiler could have optimized external bus access and combined the two byte reads into one word read. This could result in unexpected behaviour. But most probably I'm wrong.
    Actually, the configuration of external bus and, most importantly, the actual generated code could help a lot in the investigation.
    Regards,
    Mike

Children
No data