EmbeddedRelated.com
Forums

interesting SPI and UART communication problem

Started by yvancastilloux October 30, 2008
Hi all,

I need some insight to figure out the cause of the problem. I hope
this might help other people as well. Here it is:

I have an embedded system, based on the x1612 MCU running at 8 MHz,
that communicates via SPI and UART with two external modules. These
two modules both initiate the communication. I would like to have my
module to be able to be waken up by an interrupt in both cases.

I use the UART0 port for the UART communication and SPI1 for the SPI
communication. So there should not be any conflict.

My UART ISR is very short, just enough to store a byte in a buffer.
The SPI ISR, initiated by a separate line, is rather long. Once in the
ISR, I can receive--by polling--and transmit up to 200 bytes at a baud
rate of 1 MHz. I assumed that I could service the UART ISR while
servicing the "long" SPI ISR with interrupt nesting.

When the UART communication is set at 115200, I get an overrun error I
would say every 500 bytes, which I did not expect. Then, I assumed
that this problem would have been eliminated at a slower baud rate of
9600. Unexpectedly, this overrun error happened more frequently at
9600, i.e. it happened every 50 bytes (roughly the increase was at a
ratio similar to 115200/9600).

I find this strange. Don't I have more time at 9600 to perform other
task such as SPI communications? Why do I get more overrun errors?

I would really appreciate any help. I have been spending days on this
and it's getting frustrating.

Regards,

Yvan

Beginning Microcontrollers with the MSP430

Could be that you are not actually servicing any interupts during the
first. Try enabling global interupts in the ISR (I.e eint command).

Rgds,

Hani

On 31/10/2008, at 1:08 AM, "yvancastilloux" wrote:

> Hi all,
>
> I need some insight to figure out the cause of the problem. I hope
> this might help other people as well. Here it is:
>
> I have an embedded system, based on the x1612 MCU running at 8 MHz,
> that communicates via SPI and UART with two external modules. These
> two modules both initiate the communication. I would like to have my
> module to be able to be waken up by an interrupt in both cases.
>
> I use the UART0 port for the UART communication and SPI1 for the SPI
> communication. So there should not be any conflict.
>
> My UART ISR is very short, just enough to store a byte in a buffer.
> The SPI ISR, initiated by a separate line, is rather long. Once in the
> ISR, I can receive--by polling--and transmit up to 200 bytes at a baud
> rate of 1 MHz. I assumed that I could service the UART ISR while
> servicing the "long" SPI ISR with interrupt nesting.
>
> When the UART communication is set at 115200, I get an overrun error I
> would say every 500 bytes, which I did not expect. Then, I assumed
> that this problem would have been eliminated at a slower baud rate of
> 9600. Unexpectedly, this overrun error happened more frequently at
> 9600, i.e. it happened every 50 bytes (roughly the increase was at a
> ratio similar to 115200/9600).
>
> I find this strange. Don't I have more time at 9600 to perform other
> task such as SPI communications? Why do I get more overrun errors?
>
> I would really appreciate any help. I have been spending days on this
> and it's getting frustrating.
>
> Regards,
>
> Yvan

Well this is what I"m doing here...

interrupt(PORT1_VECTOR) DualMcu_Rx(Void_t){

if(Read_CsApp_Flag())
{
// Remove the pending interrupt flag
RemoveCsAppIntFlag();
_EINT();
DualMCULowLayerProtocol();
}

return;

}
--- In m..., Hani Chahine wrote:
>
> Could be that you are not actually servicing any interupts during the
> first. Try enabling global interupts in the ISR (I.e eint command).
>
> Rgds,
>
> Hani
>
> On 31/10/2008, at 1:08 AM, "yvancastilloux" wrote:
>
> > Hi all,
> >
> > I need some insight to figure out the cause of the problem. I hope
> > this might help other people as well. Here it is:
> >
> > I have an embedded system, based on the x1612 MCU running at 8 MHz,
> > that communicates via SPI and UART with two external modules. These
> > two modules both initiate the communication. I would like to have my
> > module to be able to be waken up by an interrupt in both cases.
> >
> > I use the UART0 port for the UART communication and SPI1 for the SPI
> > communication. So there should not be any conflict.
> >
> > My UART ISR is very short, just enough to store a byte in a buffer.
> > The SPI ISR, initiated by a separate line, is rather long. Once in the
> > ISR, I can receive--by polling--and transmit up to 200 bytes at a baud
> > rate of 1 MHz. I assumed that I could service the UART ISR while
> > servicing the "long" SPI ISR with interrupt nesting.
> >
> > When the UART communication is set at 115200, I get an overrun error I
> > would say every 500 bytes, which I did not expect. Then, I assumed
> > that this problem would have been eliminated at a slower baud rate of
> > 9600. Unexpectedly, this overrun error happened more frequently at
> > 9600, i.e. it happened every 50 bytes (roughly the increase was at a
> > ratio similar to 115200/9600).
> >
> > I find this strange. Don't I have more time at 9600 to perform other
> > task such as SPI communications? Why do I get more overrun errors?
> >
> > I would really appreciate any help. I have been spending days on this
> > and it's getting frustrating.
> >
> > Regards,
> >
> > Yvan
> >
> >
>
>

Is it possible that during DualMCULowLayerProtocol(); you get another
Port-1 interrupt?

Anyway, there will be periods of time UART0 interrupts (a) are
deferred and (b) are acknowledged. Depends on the UART0 data-rate,
during (a) you get a SINGLE data overrun error but actuarially missed
a lot of UART0 interrupts. During (b) you can handle many successful
UART0 interrupts. For example, you may get ~500 bytes during (b) at
115.2 kb/s but can only get ~50 bytes at 9.6 kb/s. You get a single
data overrun in either case during (a) but have no idea how many bytes
are missed.

--- In m..., "yvancastilloux" wrote:
>
> Well this is what I"m doing here...
>
> interrupt(PORT1_VECTOR) DualMcu_Rx(Void_t){
>
>
> if(Read_CsApp_Flag())
> {
> // Remove the pending interrupt flag
> RemoveCsAppIntFlag();
> _EINT();
> DualMCULowLayerProtocol();
> }
>
> return;
>
> }
> --- In m..., Hani Chahine wrote:
> >
> > Could be that you are not actually servicing any interupts during
the
> > first. Try enabling global interupts in the ISR (I.e eint command).
> >
> > Rgds,
> >
> > Hani
> >
> > On 31/10/2008, at 1:08 AM, "yvancastilloux" wrote:
> >
> > > Hi all,
> > >
> > > I need some insight to figure out the cause of the problem. I hope
> > > this might help other people as well. Here it is:
> > >
> > > I have an embedded system, based on the x1612 MCU running at 8 MHz,
> > > that communicates via SPI and UART with two external modules. These
> > > two modules both initiate the communication. I would like to have my
> > > module to be able to be waken up by an interrupt in both cases.
> > >
> > > I use the UART0 port for the UART communication and SPI1 for the SPI
> > > communication. So there should not be any conflict.
> > >
> > > My UART ISR is very short, just enough to store a byte in a buffer.
> > > The SPI ISR, initiated by a separate line, is rather long. Once
in the
> > > ISR, I can receive--by polling--and transmit up to 200 bytes at
a baud
> > > rate of 1 MHz. I assumed that I could service the UART ISR while
> > > servicing the "long" SPI ISR with interrupt nesting.
> > >
> > > When the UART communication is set at 115200, I get an overrun
error I
> > > would say every 500 bytes, which I did not expect. Then, I assumed
> > > that this problem would have been eliminated at a slower baud
rate of
> > > 9600. Unexpectedly, this overrun error happened more frequently at
> > > 9600, i.e. it happened every 50 bytes (roughly the increase was at a
> > > ratio similar to 115200/9600).
> > >
> > > I find this strange. Don't I have more time at 9600 to perform other
> > > task such as SPI communications? Why do I get more overrun errors?
> > >
> > > I would really appreciate any help. I have been spending days on
this
> > > and it's getting frustrating.
> > >
> > > Regards,
> > >
> > > Yvan
> > >
> > >
> >
> >
> >
>
sounds good. I don't understand everthing...

A few questions:

1) I cannot receive more than 1 port-1 interrupt...
2) why would a UART interrupt be deferred? What do you mean by an
acknowledged interrupt?

3) I do verify the integrity of the data. The real test that I made is
the following: I would send a sequence of bytes from 0 to 99 and
verify the integrity at the receiving end. Roughly 5 out of 6 times I
would receive all bytes correctly at 115200 baud. On the other hand, 1
out of 3 times I correctly received the bytes at 9600 baud. Does that
make a difference in your explanations?

Many thanx again.

Yvan

--- In m..., "old_cow_yellow"
wrote:
>
> Is it possible that during DualMCULowLayerProtocol(); you get another
> Port-1 interrupt?
>
> Anyway, there will be periods of time UART0 interrupts (a) are
> deferred and (b) are acknowledged. Depends on the UART0 data-rate,
> during (a) you get a SINGLE data overrun error but actuarially missed
> a lot of UART0 interrupts. During (b) you can handle many successful
> UART0 interrupts. For example, you may get ~500 bytes during (b) at
> 115.2 kb/s but can only get ~50 bytes at 9.6 kb/s. You get a single
> data overrun in either case during (a) but have no idea how many bytes
> are missed.
>
> --- In m..., "yvancastilloux" wrote:
> >
> > Well this is what I"m doing here...
> >
> > interrupt(PORT1_VECTOR) DualMcu_Rx(Void_t){
> >
> >
> > if(Read_CsApp_Flag())
> > {
> > // Remove the pending interrupt flag
> > RemoveCsAppIntFlag();
> > _EINT();
> > DualMCULowLayerProtocol();
> > }
> >
> > return;
> >
> > }
> >
> >
> > --- In m..., Hani Chahine wrote:
> > >
> > > Could be that you are not actually servicing any interupts during
> the
> > > first. Try enabling global interupts in the ISR (I.e eint command).
> > >
> > > Rgds,
> > >
> > > Hani
> > >
> > > On 31/10/2008, at 1:08 AM, "yvancastilloux" wrote:
> > >
> > > > Hi all,
> > > >
> > > > I need some insight to figure out the cause of the problem. I hope
> > > > this might help other people as well. Here it is:
> > > >
> > > > I have an embedded system, based on the x1612 MCU running at 8
MHz,
> > > > that communicates via SPI and UART with two external modules.
These
> > > > two modules both initiate the communication. I would like to
have my
> > > > module to be able to be waken up by an interrupt in both cases.
> > > >
> > > > I use the UART0 port for the UART communication and SPI1 for
the SPI
> > > > communication. So there should not be any conflict.
> > > >
> > > > My UART ISR is very short, just enough to store a byte in a
buffer.
> > > > The SPI ISR, initiated by a separate line, is rather long. Once
> in the
> > > > ISR, I can receive--by polling--and transmit up to 200 bytes at
> a baud
> > > > rate of 1 MHz. I assumed that I could service the UART ISR while
> > > > servicing the "long" SPI ISR with interrupt nesting.
> > > >
> > > > When the UART communication is set at 115200, I get an overrun
> error I
> > > > would say every 500 bytes, which I did not expect. Then, I assumed
> > > > that this problem would have been eliminated at a slower baud
> rate of
> > > > 9600. Unexpectedly, this overrun error happened more frequently at
> > > > 9600, i.e. it happened every 50 bytes (roughly the increase
was at a
> > > > ratio similar to 115200/9600).
> > > >
> > > > I find this strange. Don't I have more time at 9600 to perform
other
> > > > task such as SPI communications? Why do I get more overrun errors?
> > > >
> > > > I would really appreciate any help. I have been spending days on
> this
> > > > and it's getting frustrating.
> > > >
> > > > Regards,
> > > >
> > > > Yvan
> > > >
> > > >
> > >
> > >
> > >
> > >
>
Thank you for your feedback.

Just to let you know that I'm getting very strange behavior. When I
erase the function that is supposed to listen to a SPI message in the
function DualMCULowLayerProtocol in the SPI1 ISR, the USART0
interrupts don't work anymore at all (code never enteres the USART0
ISR).... hard to explain but it's very strange.

I rarely blame the compiler but I'm running a 2005 version of mspgcc.
I'll upgrade my code to the TI compiler and finally have a real
debugger. When I have new developments, I'll let you know.

Cheers,

YC

--- In m..., "old_cow_yellow"
wrote:
>
> Is it possible that during DualMCULowLayerProtocol(); you get another
> Port-1 interrupt?
>
> Anyway, there will be periods of time UART0 interrupts (a) are
> deferred and (b) are acknowledged. Depends on the UART0 data-rate,
> during (a) you get a SINGLE data overrun error but actuarially missed
> a lot of UART0 interrupts. During (b) you can handle many successful
> UART0 interrupts. For example, you may get ~500 bytes during (b) at
> 115.2 kb/s but can only get ~50 bytes at 9.6 kb/s. You get a single
> data overrun in either case during (a) but have no idea how many bytes
> are missed.
>
> --- In m..., "yvancastilloux" wrote:
> >
> > Well this is what I"m doing here...
> >
> > interrupt(PORT1_VECTOR) DualMcu_Rx(Void_t){
> >
> >
> > if(Read_CsApp_Flag())
> > {
> > // Remove the pending interrupt flag
> > RemoveCsAppIntFlag();
> > _EINT();
> > DualMCULowLayerProtocol();
> > }
> >
> > return;
> >
> > }
> >
> >
> > --- In m..., Hani Chahine wrote:
> > >
> > > Could be that you are not actually servicing any interupts during
> the
> > > first. Try enabling global interupts in the ISR (I.e eint command).
> > >
> > > Rgds,
> > >
> > > Hani
> > >
> > > On 31/10/2008, at 1:08 AM, "yvancastilloux" wrote:
> > >
> > > > Hi all,
> > > >
> > > > I need some insight to figure out the cause of the problem. I hope
> > > > this might help other people as well. Here it is:
> > > >
> > > > I have an embedded system, based on the x1612 MCU running at 8
MHz,
> > > > that communicates via SPI and UART with two external modules.
These
> > > > two modules both initiate the communication. I would like to
have my
> > > > module to be able to be waken up by an interrupt in both cases.
> > > >
> > > > I use the UART0 port for the UART communication and SPI1 for
the SPI
> > > > communication. So there should not be any conflict.
> > > >
> > > > My UART ISR is very short, just enough to store a byte in a
buffer.
> > > > The SPI ISR, initiated by a separate line, is rather long. Once
> in the
> > > > ISR, I can receive--by polling--and transmit up to 200 bytes at
> a baud
> > > > rate of 1 MHz. I assumed that I could service the UART ISR while
> > > > servicing the "long" SPI ISR with interrupt nesting.
> > > >
> > > > When the UART communication is set at 115200, I get an overrun
> error I
> > > > would say every 500 bytes, which I did not expect. Then, I assumed
> > > > that this problem would have been eliminated at a slower baud
> rate of
> > > > 9600. Unexpectedly, this overrun error happened more frequently at
> > > > 9600, i.e. it happened every 50 bytes (roughly the increase
was at a
> > > > ratio similar to 115200/9600).
> > > >
> > > > I find this strange. Don't I have more time at 9600 to perform
other
> > > > task such as SPI communications? Why do I get more overrun errors?
> > > >
> > > > I would really appreciate any help. I have been spending days on
> this
> > > > and it's getting frustrating.
> > > >
> > > > Regards,
> > > >
> > > > Yvan
> > > >
> > > >
> > >
> > >
> > >
> > >
>