/* ---------------------------------------------------------------------------
 * ssp0ISR.c - v0.1                                     (c) 2007 Micro-key bv
 * ---------------------------------------------------------------------------
 * Micro-key bv
 * Industrieweg 28, 9804 TG Noordhorn
 * Postbus 92, 9800 AB Zuidhorn
 * The Netherlands
 * Tel: +31 594 503020
 * Fax: +31 594 505825
 * Email: support@microkey.nl  
 * Web: www.microkey.nl
 * ---------------------------------------------------------------------------
 * Description: Interrupt service routine for SSP0
 * ---------------------------------------------------------------------------
 * Version(s):  0.1, 28-11-2007, fvds.
 *                   Creation.
 * ---------------------------------------------------------------------------
 */

/* ---------------------------------------------------------------------------
 * System include files
 * ---------------------------------------------------------------------------
 */
#include <stdio.h>
#include <stdlib.h>


/* ---------------------------------------------------------------------------
 * Application include files
 * ---------------------------------------------------------------------------
 */
#include "LPC23xx.h"
#include "types.h"

#include "ssp0ISR.h"
//#include "armVIC.h"

/* FreeRTOS includes */
#include "FreeRTOS.h"
#include "Task.h"
#include "queue.h"


/* ---------------------------------------------------------------------------
 * Local constant and macro definitions
 * ---------------------------------------------------------------------------
 */

/* ---------------------------------------------------------------------------
 * Global variable definitions
 * ---------------------------------------------------------------------------
 */
extern xQueueHandle ssp0DispatchedIsrQueue;

/* ---------------------------------------------------------------------------
 * Local variable definitions
 * ---------------------------------------------------------------------------
 */
/* statistics of all the interrupts */
static volatile UINT32 interruptRxStat = 0;
static volatile UINT32 interruptOverRunStat = 0;
static volatile UINT32 interruptRxTimeoutStat = 0;
static UINT8 receivedByte;


/* ---------------------------------------------------------------------------
 * Local function definitions
 * ---------------------------------------------------------------------------
 */
static void ssp0Handler( void );


void ssp0ISR( void )
{
    /* Save the context of the interrupted task. */
    portSAVE_CONTEXT();
        {
        ssp0Handler();
        }
    /* Restore the context of whichever task is going to run once the interrupt
    completes. */
    portRESTORE_CONTEXT();
}

void ssp0Handler( void )
{
    UINT32 regValue;

    regValue = SSP0MIS;
    if ( regValue & SSPMIS_RORMIS ) /* Receive overrun interrupt */
        {
        interruptOverRunStat++;
        SSP0ICR = SSPICR_RORIC; /* clear interrupt */
        }
      
    if ( regValue & SSPMIS_RTMIS )  /* Receive timeout interrupt */
        {
        interruptRxTimeoutStat++;
        
        while ( SSP0SR & SSPSR_RNE ) // While not empty
            {
            receivedByte = SSP0DR;
            xQueueSendToBackFromISR( ssp0DispatchedIsrQueue, &receivedByte, pdFALSE );
            }
        
        SSP0ICR = SSPICR_RTIC;  /* clear interrupt */
        }

    /* please be aware that, in main and ISR, CurrentRxIndex and CurrentTxIndex
    are shared as global variables. It may create some race condition that main
    and ISR manipulate these variables at the same time. SSPSR_BSY checking (polling)
    in both main and ISR could prevent this kind of race condition */
    if ( regValue & SSPMIS_RXMIS )  /* Rx at least half full */
        {
        interruptRxStat++;  /* receive until it's empty */
        
        while ( SSP0SR & SSPSR_RNE ) // While not empty
            {
            receivedByte = SSP0DR;
            xQueueSendToBackFromISR( ssp0DispatchedIsrQueue, &receivedByte, pdFALSE );
            }
        }

    VICVectAddr = 0;           /* Acknowledge Interrupt */
}

