gas sensor

gas sensor

Search This Blog

Sunday, January 31, 2010

part 6
Code
this code show how to set interrupts and use receive/transmit of data
while taking into account the erratas both in mcu and XBee modules



/*!
* \brief This function will initialized the ZIGBEE model
*
* \parameters void
*
*/
void ZIGBEE_init( void)
{
#if (ZIGBEE_TELEMETRY == ENABLED)


// set ZIGBEE USART pins
static const gpio_map_t ZIGBEE_USART_GPIO_MAP =
{
{GPIO_ZIGBEE_USART_RX_PIN, GPIO_ZIGBEE_USART_RX_FUNCTION},
{GPIO_ZIGBEE_USART_TX_PIN, GPIO_ZIGBEE_USART_TX_FUNCTION},
{GPIO_ZIGBEE_USART_CTS_PIN, GPIO_ZIGBEE_USART_CTS_FUNCTION},
{GPIO_ZIGBEE_USART_RTS_PIN, GPIO_ZIGBEE_USART_RTS_FUNCTION}
};


// PDCA RX channel options
static const pdca_channel_options_t PDCA_OPTIONS_RX =
{
.addr = NULL, // memory address
.pid = AVR32_PDCA_PID_ZIGBEE_RX, // data are received on RX line.
.size = 0, // transfer counter
.r_addr = NULL, // next memory address
.r_size = 0, // next transfer counter
.transfer_size = AVR32_PDCA_BYTE // select size of the transfer
};


// PDCA TX channel options
static const pdca_channel_options_t PDCA_OPTIONS_TX =
{
.addr = NULL, // memory address
.pid = AVR32_PDCA_PID_ZIGBEE_TX, // data are sent on TX line.
.size = 0, // transfer counter
.r_addr = NULL, // next memory address
.r_size = 0, // next transfer counter
.transfer_size = AVR32_PDCA_BYTE // select size of the transfer
};


// Init PDCA channel with the pdca_options.
pdca_init_channel(PDCA_CHANNEL_ZIGBEE_RX, &PDCA_OPTIONS_RX); // init PDCA channel with options.
pdca_init_channel(PDCA_CHANNEL_ZIGBEE_TX, &PDCA_OPTIONS_TX); // init PDCA channel with options.


// Register PDCA ZIGBEE_USART IRQ interrupt to simulate RTS,CTS
pdca_set_ZIGBEE_RTS_irq();
pdca_set_ZIGBEE_CTS_irq();


// Enable PDCA transfer interrupt when completed
pdca_enable_interrupt_transfer_complete( PDCA_CHANNEL_ZIGBEE_RX);
pdca_enable_interrupt_transfer_complete( PDCA_CHANNEL_ZIGBEE_TX);


// Enable now the pdca.
pdca_enable(PDCA_CHANNEL_ZIGBEE_RX);
pdca_enable(PDCA_CHANNEL_ZIGBEE_TX);


// Options for ZIGBEE USART.
usart_options_t zigbee_usart_options =
{
.baudrate = GPIO_ZIGBEE_USART_BAUDRATE,
.charlength = 8,
.paritytype = USART_NO_PARITY,
.stopbits = USART_1_STOPBIT,
.channelmode = USART_NORMAL_CHMODE
};


// Setup GPIO for ZIGBEE USART.
gpio_enable_module(ZIGBEE_USART_GPIO_MAP,
sizeof(ZIGBEE_USART_GPIO_MAP) / sizeof(ZIGBEE_USART_GPIO_MAP[0]));


// Initialize it in RS232 mode (not usart_init_hw_handshaking).
usart_init_rs232(ZIGBEE_USART, &zigbee_usart_options, CLK_USART);


#endif //ZIGBEE_TELEMETRY
}


/*! \brief input PDCA interrupt setting.
* Register the PDCA interrupt handler to the interrupt controller
*/
void pdca_set_ZIGBEE_RTS_irq(void)
{
#if (ZIGBEE_TELEMETRY == ENABLED)
#if __GNUC__
// Disable all interrupt/exception.
Disable_global_interrupt();


// Register the compare interrupt handler to the interrupt controller
// and enable the compare interrupt.
// (__int_handler) &pdca_ZIGBEE_RTS_int_handler The handler function to register.
// AVR32_PDCA_IRQ_0 The interrupt line to register to.
// AVR32_INTC_INT0 The priority level to set for this interrupt line.
// INTC_register_interrupt(__int_handler handler, int line, int priority);


INTC_register_interrupt( (__int_handler) &pdca_ZIGBEE_RTS_int_handler, PDCA_CHANNEL_INT_RX, AVR32_INTC_INT0);


#endif


// Enable all interrupt/exception.
Enable_global_interrupt();
#endif
}


/*! \USART brief RTS setting
*/
#if __GNUC__
__attribute__((naked))
#elif __ICCAVR32__
#pragma shadow_registers = full // Naked.
#endif
static void pdca_ZIGBEE_RTS_int_handler( void)
{
#if (ZIGBEE_TELEMETRY == ENABLED)
/* This ISR can cause a context switch, so the first statement must be a
call to the portENTER_SWITCHING_ISR() macro. This must be BEFORE any
variable declarations. */
portENTER_SWITCHING_ISR();


// prevent re-entering
pdca_disable_interrupt_transfer_complete( PDCA_CHANNEL_ZIGBEE_RX);
// close !(RTS), stop transfer
ZIGBEE_USART->cr = AVR32_USART_CR_RTSDIS_MASK;


portEXIT_SWITCHING_ISR();
#endif
}


/*! \brief input PDCA interrupt setting.
* Register the PDCA interrupt handler to the interrupt controller
*/
void pdca_set_ZIGBEE_CTS_irq(void)
{
#if (ZIGBEE_TELEMETRY == ENABLED)
#if __GNUC__
// Disable all interrupt/exception.
Disable_global_interrupt();


// (__int_handler) &pdca_ZIGBEE_CTS_int_handler The handler function to register.
// AVR32_PDCA_IRQ_0 The interrupt line to register to.
// AVR32_INTC_INT0 The priority level to set for this interrupt line.
// INTC_register_interrupt(__int_handler handler, int line, int priority);


INTC_register_interrupt( (__int_handler) &pdca_ZIGBEE_CTS_int_handler, PDCA_CHANNEL_INT_TX, AVR32_INTC_INT0);


#endif


// Enable all interrupt/exception.
Enable_global_interrupt();
#endif
}




/*! \USART brief CTS setting
 */
#if __GNUC__
__attribute__((naked))
#elif __ICCAVR32__
#pragma shadow_registers = full   // Naked.
#endif
static void pdca_ZIGBEE_CTS_int_handler( void)
{
#if (ZIGBEE_TELEMETRY == ENABLED)
/* This ISR can cause a context switch, so the first statement must be a
call to the portENTER_SWITCHING_ISR() macro.  This must be BEFORE any
variable declarations. */
portENTER_SWITCHING_ISR();


// prevent re-entering
pdca_disable_interrupt_transfer_complete( PDCA_CHANNEL_ZIGBEE_TX);


// disable hardware handshaking mode.
if (ZIGBEE_USART->mr & (AVR32_USART_MR_MODE_HARDWARE << AVR32_USART_MR_MODE_OFFSET))
ZIGBEE_USART->mr &= ~(AVR32_USART_MR_MODE_HARDWARE << AVR32_USART_MR_MODE_OFFSET);


portEXIT_SWITCHING_ISR();
#endif
}






/*!
 * \brief This function will read zigbee data from usart
 * \to data buffer using the pdca channel
 *
 * \param: pdata pointer to receiving buffer, sdata size to read in bytes
 */
static void pdca_ZIGBEE_receive( void * pdata, unsigned int sdata)
{
#if (ZIGBEE_TELEMETRY == ENABLED)
// overhead byte
unsigned portCHAR ucOverHead;


// wait last write end so hardware handshaking mode is disabled
while(!(pdca_get_transfer_status(PDCA_CHANNEL_ZIGBEE_TX) & PDCA_TRANSFER_COMPLETE));


// wait last read end, new receive can be handled
while(!(pdca_get_transfer_status(PDCA_CHANNEL_ZIGBEE_RX) & PDCA_TRANSFER_COMPLETE));


// read last byte overhead from last receive
if (usart_test_hit(ZIGBEE_USART))
ucOverHead=(ZIGBEE_USART->rhr & AVR32_USART_RHR_RXCHR_MASK) >> AVR32_USART_RHR_RXCHR_OFFSET;


// load channel
pdca_reload_channel( PDCA_CHANNEL_ZIGBEE_RX, (void *) pdata, sdata);


// Enable PDCA transfer interrupt when completed
pdca_enable_interrupt_transfer_complete( PDCA_CHANNEL_ZIGBEE_RX);


//set !(RTS), start transfer
ZIGBEE_USART->cr = AVR32_USART_CR_RTSEN_MASK;
#endif //#if (ZIGBEE_TELEMETRY == ENABLED)
}




/*!
* \brief This function will transmitting zigbee data to usart
* \from data buffer using the pdca channel
*
* \param: pdata pointer to transmitting buffer, sdata size to read in bytes
*/
static void pdca_ZIGBEE_transmit( void * pdata, unsigned int sdata)
{
#if (ZIGBEE_TELEMETRY == ENABLED)
// wait last read end so hardware handshaking mode can be enabled
while(!(pdca_get_transfer_status(PDCA_CHANNEL_ZIGBEE_RX) & PDCA_TRANSFER_COMPLETE));


// wait last write end, new transmit can be set
while(!(pdca_get_transfer_status(PDCA_CHANNEL_ZIGBEE_TX) & PDCA_TRANSFER_COMPLETE));


// Set hardware handshaking mode.
ZIGBEE_USART->mr = (ZIGBEE_USART->mr & ~AVR32_USART_MR_MODE_MASK) |
AVR32_USART_MR_MODE_HARDWARE << AVR32_USART_MR_MODE_OFFSET;


// write params
pdca_reload_channel( PDCA_CHANNEL_ZIGBEE_TX, (void *) pdata, sdata);


// Enable PDCA transfer interrupt when completed
pdca_enable_interrupt_transfer_complete( PDCA_CHANNEL_ZIGBEE_TX);
#endif //#if (ZIGBEE_TELEMETRY == ENABLED)
}

No comments:

Post a Comment