EmbeddedRelated.com
Forums
The 2024 Embedded Online Conference

ez430-rf2500 sending from Access Point to End Device

Started by "eng...@ymail.com [msp430]" February 29, 2016
Hi there, i am working on a home automation project and am using Ez430-RF2500 emulator and Ez430-RF2500t target boards, i have to modify the demo project so the base node (named access point AP in the demo) can send data to the sensor nodes (named end device ED in the demo), some c language files which their name starts with nwk contain a lot of settings and they contain all simpliciTI protocol functions and variables, i want to know which of these files (or other files in the demo project) i have to modify so the AP can send to the ED.

Thanks in advance

Beginning Microcontrollers with the MSP430

I'm curious if someone can explain to me the (negative?) effects of trying to send UART bytes directly from my Interrupt Service Routine. Is this bad design practice because now my ISR will take longer to execute? Should I be using DMA to TX data here? Thanks in advance.

static void ParseRxData(const uint8_t rx_byte)
{
// Only Allow ASCII Characters to be loaded into buffer
// This will drop CR/LF etc, won't go in gRxBuffer
if (rx_byte >= 0x20)
gRxBuffer[gWrIndex++] = tolower(rx_byte); // stuff lowercase only into buffer

UartSendChar(rx_byte);

if (rx_byte == 0x0A) // End of Command
{
gRxBuffer[gWrIndex] = 0; // Add null pointer to end
gFlagCmdReady = true; // Set Global Flag Ready Command
gWrIndex = 0;
}
}

//******************************************************************************
//
//This is the USCI_A1 interrupt vector service routine.
//
//******************************************************************************
#if defined(__TI_COMPILER_VERSION__) || defined(__IAR_SYSTEMS_ICC__)
#pragma vector=USCI_A1_VECTOR
__interrupt
#elif defined(__GNUC__)
__attribute__((interrupt(USCI_A1_VECTOR)))
#endif
void EUSCI_A1_ISR(void)
{
uint8_t RXData;
switch(__even_in_range(UCA1IV,USCI_UART_UCTXCPTIFG))
{
case USCI_NONE: break;
case USCI_UART_UCRXIFG:
RXData = EUSCI_A_UART_receiveData(EUSCI_A1_BASE);
ParseRxData(RXData);
break;
case USCI_UART_UCTXIFG: break;
case USCI_UART_UCSTTIFG: break;
case USCI_UART_UCTXCPTIFG: break;
}
}
Without seeing how that compiles it is hard to say. What I can say is
that transmitting inside the interrupt, provided your interrupt is
small, is generally the fastest and most efficient way to do it. The DMA
on the MSP430 is not a true DMA in that it steals clocks from the CPU so
isn't as efficient as a traditional DMA. If you have DMA and your
messages are reasonably long then it's worthwhile usign DMA most of the
time. You have to weigh the DMA set up overhead, and the loss of CPU
cycles against the savings made, and make allowances for all scenarios

This is a typical UART handler that handles both Tx and RX although RX
isn't used in this case.

Handling the RX may seem pedantic, but register RAM corruption does
occur (I probably made a tidy living for many years off of that common
omission) and unless you have other more complex safeguards in place
this is a simple way of avoiding erroneous transmission. It should have
another instruction prior to exit that clears the RXIFG so that the
false int doesn't keep re-occurring, but it wasn't in my original code
so I left it so I could point out my own error.

;****** THIS UART A0 IS USED FOR RF COMMS
USCABTX_ISR: ;UART1 TX VECTOR, TRAP IF UNUSED.
BIT #UCA0TXIFG,&IFG2 ;Test Tx int flag
JNZ TXHB0 ;jump if set
BIC #LPM3,0(SP) ;set low poer mode on exit
RETI ;else exit
TXHB0:
MOV &TX_PTR,R12 ;set up to use indexed fetch
INC &TX_PTR
MOV.B TX_BUFFER(R12),&UCA0TXBUF ;write next byte to Tx OUTPUT reg
DEC DIGITS ;DIGITS is a reserved register
for tracking the Tx size
JNZ ENDTX ;if not last byte continue
BIC.B #UCA0TXIE,&IE2 ;else disable ISR
BIS.B #GREEN,&P2OUT ;turn Green Tx LED off
BIC #LPM3,0(SP) ;and exit in LPM3
ENDTX:
RETI

Al
On 30/09/2016 12:57 AM, x...@yahoo.com [msp430] wrote:
> I'm curious if someone can explain to me the (negative?) effects of
> trying to send UART bytes directly from my Interrupt Service Routine.
> Is this bad design practice because now my ISR will take longer to
> execute? Should I be using DMA to TX data here? Thanks in advance.
> static void ParseRxData(const uint8_t rx_byte)
>
> {
>
> // Only Allow ASCII Characters to be loaded into buffer
>
> // This will drop CR/LF etc, won't go in gRxBuffer
>
> if (rx_byte >= 0x20)
>
> gRxBuffer[gWrIndex++] = tolower(rx_byte); // stuff lowercase
> only into buffer
> UartSendChar(rx_byte);
> if (rx_byte == 0x0A) // End of Command
>
> {
>
> gRxBuffer[gWrIndex] = 0; // Add null pointer to end
>
> gFlagCmdReady = true; // Set Global Flag Ready Command
>
> gWrIndex = 0;
>
> }
>
> }
>
> //******************************************************************************
>
> //
>
> //This is the USCI_A1 interrupt vector service routine.
>
> //
>
> //******************************************************************************
>
> #if defined(__TI_COMPILER_VERSION__) || defined(__IAR_SYSTEMS_ICC__)
>
> #pragma vector=USCI_A1_VECTOR
>
> __interrupt
>
> #elif defined(__GNUC__)
>
> __attribute__((interrupt(USCI_A1_VECTOR)))
>
> #endif
>
> void EUSCI_A1_ISR(void)
>
> {
>
> uint8_t RXData;
>
> switch(__even_in_range(UCA1IV,USCI_UART_UCTXCPTIFG))
>
> {
>
> case USCI_NONE: break;
>
> case USCI_UART_UCRXIFG:
>
> RXData = EUSCI_A_UART_receiveData(EUSCI_A1_BASE);
>
> ParseRxData(RXData);
>
> break;
>
> case USCI_UART_UCTXIFG: break;
>
> case USCI_UART_UCSTTIFG: break;
>
> case USCI_UART_UCTXCPTIFG: break;
>
> }
>
> }
>
Hi xilverbolt,

you are receiving a byte and just send it.
UartSendChar() is typically waiting for the sending UART to be free again -
and will block your interrupts and CPU for this time - maybe not a good
idea. You should at least enable the interrupts before calling ParseRXData
(EINT()). However, in case the sending and transmitting UART are both
working at the same speed, this will never happen.

Another point: I would not call subroutines from the interrupt, this need
much more cycles e.g. for saving all registers to stack. In a short int-
routine, as in your example, only a few registern are needed to be pushed
to the stack and popped. However maybe the compiler is good one and is
inlining your subroutine automatically. Another advantage is, you will see
what happen in only a few lines - e.g. that UartSendChar() is blocking your
code.
Encapsulation of code in subroutines is often a good idea, but sometimes
not.

In case you just want to copy a byte from uarta to uartb - this can be done
with the DMA only - just code for the setup is required, no active code
during execution of the task required and no blocking of the CPU, for my
opinion the best solution - however you need some time to find out the
right setup bits ;-). It is possible to have a additional rx interrupt that
is handling the buffering of the bytes only.

Matthias

"x...@yahoo.com [msp430]" :

> I'm curious if someone can explain to me the (negative?) effects of
> trying to send UART bytes directly from my Interrupt Service Routine.
> Is this bad design practice because now my ISR will take longer to
> execute? Should I be using DMA to TX data here? Thanks in advance.
>
>
> static void ParseRxData(const uint8_t rx_byte)
> {
> // Only Allow ASCII Characters to be loaded into buffer
> // This will drop CR/LF etc, won't go in gRxBuffer
> if (rx_byte >= 0x20)
> gRxBuffer[gWrIndex++] = tolower(rx_byte); // stuff lowercase
> only into buffer
>
>
> UartSendChar(rx_byte);
>
>
> if (rx_byte == 0x0A) // End of Command
> {
> gRxBuffer[gWrIndex] = 0; // Add null pointer to end
> gFlagCmdReady = true; // Set Global Flag Ready Command
> gWrIndex = 0;
> }
> }
>
>
>
>
> //**********************************************************************
> ******** //
> //This is the USCI_A1 interrupt vector service routine.
> //
> //**********************************************************************
> ******** #if defined(__TI_COMPILER_VERSION__) ||
> defined(__IAR_SYSTEMS_ICC__) #pragma vector=USCI_A1_VECTOR
> __interrupt
> #elif defined(__GNUC__)
> __attribute__((interrupt(USCI_A1_VECTOR)))
> #endif
> void EUSCI_A1_ISR(void)
> {
> uint8_t RXData;
> switch(__even_in_range(UCA1IV,USCI_UART_UCTXCPTIFG))
> {
> case USCI_NONE: break;
> case USCI_UART_UCRXIFG:
> RXData = EUSCI_A_UART_receiveData(EUSCI_A1_BASE);
> ParseRxData(RXData);
> break;
> case USCI_UART_UCTXIFG: break;
> case USCI_UART_UCSTTIFG: break;
> case USCI_UART_UCTXCPTIFG: break;
> }
> }
>


Posted by: Matthias Weingart




The 2024 Embedded Online Conference