We are working with a proprietary board based on the Elektronikladen
CardS12.D64 using ICC12 and NoICE with the ComPOD12 Pro BDM. The
processor boots up in the TwinPeeks monitor and jumps to the user code
at 0x8000 where all of our code starts (including startup and init).
SCI1 is interrupt driven RS485. SCI0 is polled RS232 half-duplex.
SCI0 set up:
SCI0CR2=TE+RE
SCI1 is outputting a string, so it is set up as:
SCI1CR2=TIE+TE+RE
Initially I did not have any ISR for SCI0, because no interrupts were
to be set. BUT, I found out that I was ALWAYS receiving an interrupt
on SCI0.
So now in BOTH ISR functions I check SR1 and respond accordingly.
I set up NoICE and put
asm(" BGND");
in both ISR functions and let NoICE run it.
Of course, when it stops at SCI0ISR, TDRE+TC are set and nothing else.
I check both SCI0SR1 and SCI1SR1 and deal with both (either putChar
or getChar for each according to the flags).
Why am I getting SCI0 interrupts when none are set and not getting any
SCI1 interrupts?
locations for the TwinPeeks vectors are:
*(int *)0x3FC5 = (int)NETINT; // SCI1 RS485 interrupt driven
*(int *)0x3FC2 = (int)SCIINT; // SCI0 Serial RS232 polled
An assembler "JMP" instruction precedes the address so that TwinPeeks
will jump to the ISR which ends in the "RTI" instruction.
void SCIINT(void)
{
INTU8 dummy;
netSR1 = SCI1SR1; // read SCI 1 Status Register to clear &
analyze it
sciSR1 = SCI0SR1; // read SCI 0 Status Register to clear &
analyze it
asm(" bgnd"); /* ### for DEBUG */
asm(" nop"); /* ### for DEBUG */
asm(" nop"); /* ### for DEBUG */
if (sciSR1 & (OR + NF + FE + PF))
{
/* Receive ERROR */
dummy = SCI0DR; // clear data regi of ?junk?
}
else if (sciSR1 & RDRF)
{
if (SCI_FLG == SCI_RECEIVE)
{
/* do receive */
//cmdRecv();
getCharSCI();
}
else
{
/* clear data register anyway */
dummy = SCI0DRL;
} /* end if else */
}
if (sciSR1 & (TDRE + TC))
{
/* if data availabe for transmission, do transmit */
if (txBusy)
{
//cmdSend();
putCharSCI();
} /* end if */
} /* end if else */
// check the OTHER serial port for interrupts ALSO
if (netSR1 & (OR + NF + FE + PF))
{
/* Receive ERROR */
}
else if (netSR1 & RDRF)
{
/* do receive */
getCharNet();
}
else if (netSR1 & (TDRE + TC))
{
if (ntxBusy)
{
/* do transmit */
putCharNet();
} /* end if */
} /* end if else */
return;
} /* SCIINT() */
/******************************************************************************/
void NETINT(void)
{
INTU8 dummy;
sciSR1 = SCI0SR1; // read SCI Status Register to clear &
analyze it
netSR1 = SCI1SR1; // read SCI Status Register to clear & analyze it
asm(" bgnd"); /* ### for DEBUG */
asm(" nop"); /* ### for DEBUG */
asm(" nop"); /* ### for DEBUG */
if (netSR1 & (RDRF + TDRE + TC))
{
if (netDir_FLG == SCI_RECEIVE)
{
/* do receive */
NET_ID();
}
else
{
/* do transmit */
NET_SEND();
} /* end if else */
} /* end if else */
// check the OTHER serial port for interrupts ALSO
if (sciSR1 & (OR + NF + FE + PF))
{
/* Receive ERROR */
dummy = SCI0DRL; // clear data regi of ?junk?
}
else if (sciSR1 & RDRF)
{
if (SCI_FLG == SCI_RECEIVE)
{
/* do receive */
getCharSCI();
} /* end if else */
} /* end if else */
if (sciSR1 & (TDRE + TC))
{
/* do transmit */
putCharSCI();
} /* end if else */
return;
} /* NETINT() */
If BOTH SCI0 and SCI1 are polled, no problem at all and both ports
output strings just fine. The moment I turn on SCI1CR2 = TIE+TE+RE;
disaster strikes and the processor is hung up doing SCI0ISR. (cuss)
What is going on? Is there any code I can see that properly handles
the dual SCI (polled+interrupt-driven)?
wade

(You need to be a member of 68hc12 -- send a blank email to 68hc12-subscribe@yahoogroups.com )
Waouhhh !
Your system seems to me so complicated !!!
But mybe it's not your system ?
Why only SCI1 interrupt driven, and not SCI0 ?
Below the code (simplified) I use with SCI0 and SCI1 ports, all of them
managed under interrupt.
As you can see, I use data structure handling
- buffer
- read and write pointers from and to the buffer
Now your only have to poll by a function examining if "wr" and "rd" pointer=
s
point on the same address (buffer empty) or not (something in the buffer),
and write a function reading the next byte in the buffer (and managing rd
pointer).
I use ICC12 and NoIce, with 9s12dp256 processor.
With that code, I can put breakpoint with NoIce even on interrupt service
routine, exam what the program do...
I hope this help.
Joel
//---------------------------------------------------------------------
// In a file I named Serial.c
#define SCI1_TAILLE_BUFFER_EMISSION 512
#define SCI1_TAILLE_BUFFER_RECEPTION 512
typedef struct TSci1_BufferEmission
{ Byte buffer[SCI1_TAILLE_BUFFER_EMISSION]; // buffer
Byte *wr, *rd; // pointer to read and write buffer
} TSci1_BufferEmission;
typedef struct TSci1_BufferReception
{ Byte buffer[SCI1_TAILLE_BUFFER_RECEPTION]; // buffer
Byte *wr, *rd; // pointers to read and write buffer
} TSci1_BufferReception;
// Variables file seen (buffers xmit and receive) for SCI0 and SCI1
static TSci1_BufferEmission _sci0_emission;
static TSci1_BufferReception _sci0_reception;
static TSci1_BufferEmission _sci1_emission;
static TSci1_BufferReception _sci1_reception;
void SCI1_Init (void)
{ SCI1BDH =3D ... depend on the speed
SCI1BDL =3D ... idem
SCI1CR1 =3D 0x00;
SCI1CR2 =3D 0x2c; // enable receive and xmit, int on
receive only
_sci1_emission.wr =3D _sci1_emission.rd =3D &sci1_emission.buffer[0];
}
// To transmit a char :
void SCI1_Xmit (char c)
{ // Check if there are place for the new char to transmit
*_sci1_emission.wr =3D c;
_sci1_emission.wr++;
// circulary buffer
if (_sci1_emission.wr > &_sci1_emission.buffer[TAILLE_EMISSION])
_sci1_emission.wr =3D &sci1_emission.buffer[0];
// Now, I enable interrupt for transmit the char and transmit buffer
if (SCI1SR1 & 0x80) SCI1CR2 |=3D 0x88;
}
// Interrupt service routine for SCI1
#pragma interrupt_handler ISR_Sci1
void ISR_Sci1 (void)
{ char sci_status;
=09
sci_status =3D SCI1SR1;
// Interruption received char
if (sci_status & 0x28) // RDRF 0x20 : Receive data reg full
{ *_sci1_reception.wr =3D SCI1DRL;=09
_sci1_reception.wr++;
if (_sci1_reception.wr >=3D
=09
&_sci1_reception.buffer[SCI1_TAILLE_BUFFER_RECEPTION])
_sci1_reception.wr =3D &_sci1_reception.buffer[0];
}
// Interruption transmit char
if (sci_status & 0x80) // TDRE : 0x80 ; Xmit Data Reg Empty
{ if (_sci1_emission.rd !=3D _sci1_emission.wr)
SCI1DRL =3D *_sci1_emission.rd; // xmit current char
_sci1_emission.rd++; // pr=E9pare next char
if (_sci1_emission.rd >=3D
&_sci1_emission.buffer[TAILLE_EMISSION])
_sci1_emission.rd =3D &_sci1_emission.buffer[0];
}
else // no more
char to xmit
{ SCI1CR2 &=3D 0x3f; // inhibe
interruptions
}
}
}
// The same ISR for SCI0=20
#pragma interrupt_handler ISR_Sci0
void ISR_Sci0 (void)
{ char sci_status;
=09
sci_status =3D SCI0SR1;
// Same code as SCI1, but with _sci0_emission and _sci0_reception
}
//---------------------------------------------------------------------
// In a file I named Vectors.c :
extern void ISR_Sci0 (void);
extern void ISR_Sci1 (void);
// Processeur 9S12DP256 : vecteurs interruptions en 0xff80
#pragma abs_address:0xFF80
void (*interrupt_vectors[])(void) =3D
{ .../...
ISR_Sci1, // $FFD4 SCI1
ISR_Sci0, // $FFD6 SCI0
.../...
_start, // $FFFE Reset, vector to entry point for ICC12
};=09
> -----Message d'origine-----
> De=A0: 6...@yahoogroups.com [mailto:6...@yahoogroups.com] De la part =
de
> WadeA & RebeccaM Smith
> Envoy=E9=A0: samedi 2 f=E9vrier 2008 00:41
> =C0=A0: 6...@yahoogroups.com
> Objet=A0: [68HC12] Dual SCI on 9S12D64 confused Interrupt
>=20
> We are working with a proprietary board based on the Elektronikladen
> CardS12.D64 using ICC12 and NoICE with the ComPOD12 Pro BDM. The
> processor boots up in the TwinPeeks monitor and jumps to the user code
> at 0x8000 where all of our code starts (including startup and init).
>=20
> SCI1 is interrupt driven RS485. SCI0 is polled RS232 half-duplex.
>=20
> SCI0 set up:
> SCI0CR2=3DTE+RE
>=20
> SCI1 is outputting a string, so it is set up as:
> SCI1CR2=3DTIE+TE+RE
>=20
> Initially I did not have any ISR for SCI0, because no interrupts were
> to be set. BUT, I found out that I was ALWAYS receiving an interrupt
> on SCI0.
>=20
> So now in BOTH ISR functions I check SR1 and respond accordingly.
>=20
> I set up NoICE and put
> asm(" BGND");
> in both ISR functions and let NoICE run it.
>=20
> Of course, when it stops at SCI0ISR, TDRE+TC are set and nothing else.
> I check both SCI0SR1 and SCI1SR1 and deal with both (either putChar
> or getChar for each according to the flags).
>=20
> Why am I getting SCI0 interrupts when none are set and not getting any
> SCI1 interrupts?
>=20
> locations for the TwinPeeks vectors are:
>=20
> *(int *)0x3FC5 =3D (int)NETINT; // SCI1 RS485 interrupt driven
> *(int *)0x3FC2 =3D (int)SCIINT; // SCI0 Serial RS232 polled
> An assembler "JMP" instruction precedes the address so that TwinPeeks
> will jump to the ISR which ends in the "RTI" instruction.
>=20
>=20
> void SCIINT(void)
> {
> INTU8 dummy;
>=20
> netSR1 =3D SCI1SR1; // read SCI 1 Status Register to clear &
> analyze it
> sciSR1 =3D SCI0SR1; // read SCI 0 Status Register to clear &
> analyze it
> asm(" bgnd"); /* ### for DEBUG */
> asm(" nop"); /* ### for DEBUG */
> asm(" nop"); /* ### for DEBUG */
> if (sciSR1 & (OR + NF + FE + PF))
> {
> /* Receive ERROR */
> dummy =3D SCI0DR; // clear data regi of ?junk?
> }
> else if (sciSR1 & RDRF)
> {
> if (SCI_FLG =3D=3D SCI_RECEIVE)
> {
> /* do receive */
> //cmdRecv();
> getCharSCI();
> }
> else
> {
> /* clear data register anyway */
> dummy =3D SCI0DRL;
> } /* end if else */
> }
> if (sciSR1 & (TDRE + TC))
> {
> /* if data availabe for transmission, do transmit */
> if (txBusy)
> {
> //cmdSend();
> putCharSCI();
> } /* end if */
> } /* end if else */
>=20
>=20
> // check the OTHER serial port for interrupts ALSO
> if (netSR1 & (OR + NF + FE + PF))
> {
> /* Receive ERROR */
> }
> else if (netSR1 & RDRF)
> {
> /* do receive */
> getCharNet();
> }
> else if (netSR1 & (TDRE + TC))
> {
> if (ntxBusy)
> {
> /* do transmit */
> putCharNet();
> } /* end if */
> } /* end if else */
>=20
>=20
> return;
> } /* SCIINT() */
>=20
> /************************************************************************=
*
> *****/
> void NETINT(void)
> {
> INTU8 dummy;
>=20
> sciSR1 =3D SCI0SR1; // read SCI Status Register to clear &
> analyze it
> netSR1 =3D SCI1SR1; // read SCI Status Register to clear & analyze i=
t
> asm(" bgnd"); /* ### for DEBUG */
> asm(" nop"); /* ### for DEBUG */
> asm(" nop"); /* ### for DEBUG */
>=20
> if (netSR1 & (RDRF + TDRE + TC))
> {
> if (netDir_FLG =3D=3D SCI_RECEIVE)
> {
> /* do receive */
> NET_ID();
> }
> else
> {
> /* do transmit */
> NET_SEND();
> } /* end if else */
> } /* end if else */
>=20
>=20
> // check the OTHER serial port for interrupts ALSO
> if (sciSR1 & (OR + NF + FE + PF))
> {
> /* Receive ERROR */
> dummy =3D SCI0DRL; // clear data regi of ?junk?
> }
> else if (sciSR1 & RDRF)
> {
> if (SCI_FLG =3D=3D SCI_RECEIVE)
> {
> /* do receive */
> getCharSCI();
> } /* end if else */
> } /* end if else */
>=20
> if (sciSR1 & (TDRE + TC))
> {
> /* do transmit */
> putCharSCI();
> } /* end if else */
>=20
> return;
> } /* NETINT() */
>=20
>=20
>=20
> If BOTH SCI0 and SCI1 are polled, no problem at all and both ports
> output strings just fine. The moment I turn on SCI1CR2 =3D TIE+TE+RE;
> disaster strikes and the processor is hung up doing SCI0ISR. (cuss)
>=20
> What is going on? Is there any code I can see that properly handles
> the dual SCI (polled+interrupt-driven)?
>=20
> wade
>=20
>=20
>=20
>=20
>=20
>
=20

(You need to be a member of 68hc12 -- send a blank email to 68hc12-subscribe@yahoogroups.com )