/**
 * @file tal_irq_handler.c
 *
 * @brief This file handles the interrupts generated by the transceiver.
 *
 * $Id: tal_irq_handler.c 18800 2009-10-23 08:10:55Z sschneid $
 *
 * @author    Atmel Corporation: http://www.atmel.com
 * @author    Support email: avr@atmel.com
 */
/*
 * Copyright (c) 2009, Atmel Corporation All rights reserved.
 *
 * Licensed under Atmel's Limited License Agreement --> EULA.txt
 */

/* === INCLUDES ============================================================ */

#include <stdint.h>
#include <stdbool.h>
#include <stddef.h>
#include "pal.h"
#include "return_val.h"
#include "tal.h"
#include "ieee_const.h"
#include "stack_config.h"
#include "bmm.h"
#include "qmm.h"
#include "tal_irq_handler.h"
#include "tal_rx.h"
#include "at86rf230b.h"
#include "tal_internal.h"
#include "tal_constants.h"
#include "tal_tx.h"
#include "mac_build_config.h"

/* === TYPES =============================================================== */


/* === MACROS ============================================================== */


/* === GLOBALS ============================================================= */


/* === PROTOTYPES ========================================================== */


/* === IMPLEMENTATION ====================================================== */

/**
 * @brief Transceiver interrupt handler
 *
 * This function handles the transceiver generated interrupts.
 */
void trx_irq_handler_cb(void)
{
    trx_irq_reason_t trx_irq_cause;

    trx_irq_cause = (trx_irq_reason_t)pal_trx_reg_read(RG_IRQ_STATUS);

    if (trx_irq_cause & TRX_IRQ_TRX_END)
    {
        /*
         * TRX_END reason depends on if the trx is currently used for
         * transmission or reception.
         */
#if ((MAC_START_REQUEST_CONFIRM == 1) && (defined BEACON_SUPPORT))
        if ((tal_state == TAL_TX_AUTO) || (tal_state == TAL_TX_BASIC) || (tal_state == TAL_TX_BEACON))
#else
        if ((tal_state == TAL_TX_AUTO) || (tal_state == TAL_TX_BASIC))
#endif
        {
            /* Switch to transceiver's default state: switch receiver on. */
            set_trx_state(CMD_RX_AACK_ON);

            /* Get the result and push it to the queue. */
            if (trx_irq_cause & TRX_IRQ_TRX_UR)
            {
                handle_tx_end_irq(true);            // see tal_tx.c
            }
            else
            {
                handle_tx_end_irq(false);            // see tal_tx.c
            }
        }
        else   /* Other tal_state than TAL_TX_... */
        {
            /* Handle rx done interrupt. */
            handle_received_frame_irq();    // see tal_rx.c
        }
    }

#if (DEBUG > 0)
    /* Other IRQ than TRX_END */
    if (trx_irq_cause != TRX_IRQ_TRX_END)
    {
        if (trx_irq_cause & TRX_IRQ_PLL_LOCK)
        {
            ASSERT("unexpected IRQ: TRX_IRQ_PLL_LOCK" == 0);
        }
        if (trx_irq_cause & TRX_IRQ_PLL_UNLOCK)
        {
            ASSERT("unexpected IRQ: TRX_IRQ_PLL_UNLOCK" == 0);
        }
        if (trx_irq_cause & TRX_IRQ_RX_START)
        {
            ASSERT("unexpected IRQ: TRX_IRQ_RX_START" == 0);
        }
        if (trx_irq_cause & TRX_IRQ_4)
        {
            ASSERT("unexpected IRQ: TRX_IRQ_4" == 0);
        }
        if (trx_irq_cause & TRX_IRQ_5)
        {
            ASSERT("unexpected IRQ: TRX_IRQ_5" == 0);
        }
        if (trx_irq_cause & TRX_IRQ_TRX_UR)
        {
            ASSERT("unexpected IRQ: TRX_IRQ_TRX_UR" == 0);
        }
        if (trx_irq_cause & TRX_IRQ_BAT_LOW)
        {
            ASSERT("unexpected IRQ: TRX_IRQ_BAT_LOW" == 0);
        }
    }
#endif
}/* trx_irq_handler_cb() */


/* EOF */

