aboutsummaryrefslogtreecommitdiffstats
path: root/firmware/atmel_softpack_libraries/libchip_sam3s/source/pio_it.c
diff options
context:
space:
mode:
Diffstat (limited to 'firmware/atmel_softpack_libraries/libchip_sam3s/source/pio_it.c')
-rw-r--r--firmware/atmel_softpack_libraries/libchip_sam3s/source/pio_it.c315
1 files changed, 315 insertions, 0 deletions
diff --git a/firmware/atmel_softpack_libraries/libchip_sam3s/source/pio_it.c b/firmware/atmel_softpack_libraries/libchip_sam3s/source/pio_it.c
new file mode 100644
index 0000000..48403c0
--- /dev/null
+++ b/firmware/atmel_softpack_libraries/libchip_sam3s/source/pio_it.c
@@ -0,0 +1,315 @@
+/* ----------------------------------------------------------------------------
+ * ATMEL Microcontroller Software Support
+ * ----------------------------------------------------------------------------
+ * Copyright (c) 2008, Atmel Corporation
+ *
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * - Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the disclaimer below.
+ *
+ * Atmel's name may not be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * DISCLAIMER: THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE
+ * DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
+ * OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
+ * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ----------------------------------------------------------------------------
+ */
+
+/*
+ * \file
+ */
+
+/*----------------------------------------------------------------------------
+ * Headers
+ *----------------------------------------------------------------------------*/
+
+#include "chip.h"
+
+#include <assert.h>
+
+/*----------------------------------------------------------------------------
+ * Local definitions
+ *----------------------------------------------------------------------------*/
+
+/* Maximum number of interrupt sources that can be defined. This
+ * constant can be increased, but the current value is the smallest possible
+ * that will be compatible with all existing projects. */
+#define MAX_INTERRUPT_SOURCES 7
+
+/*----------------------------------------------------------------------------
+ * Local types
+ *----------------------------------------------------------------------------*/
+
+/**
+ * Describes a PIO interrupt source, including the PIO instance triggering the
+ * interrupt and the associated interrupt handler.
+ */
+typedef struct _InterruptSource
+{
+ /* Pointer to the source pin instance. */
+ const Pin *pPin;
+
+ /* Interrupt handler. */
+ void (*handler)( const Pin* ) ;
+} InterruptSource ;
+
+/*----------------------------------------------------------------------------
+ * Local variables
+ *----------------------------------------------------------------------------*/
+
+/* List of interrupt sources. */
+static InterruptSource _aIntSources[MAX_INTERRUPT_SOURCES] ;
+
+/* Number of currently defined interrupt sources. */
+static uint32_t _dwNumSources = 0;
+
+/*----------------------------------------------------------------------------
+ * Local Functions
+ *----------------------------------------------------------------------------*/
+/*----------------------------------------------------------------------------*/
+/**
+ * \brief Stub, to handling all PIO Capture interrupts, if not defined.
+ */
+/*----------------------------------------------------------------------------*/
+//extern WEAK void PIO_CaptureHandler( void )
+//{
+//}
+
+/**
+ * \brief Handles all interrupts on the given PIO controller.
+ * \param id PIO controller ID.
+ * \param pPio PIO controller base address.
+ */
+extern void PioInterruptHandler( uint32_t id, Pio *pPio )
+{
+ uint32_t status;
+ uint32_t i;
+
+ /* Read PIO controller status */
+ status = pPio->PIO_ISR;
+ status &= pPio->PIO_IMR;
+
+ /* Check pending events */
+ if ( status != 0 )
+ {
+ TRACE_DEBUG( "PIO interrupt on PIO controller #%" PRIu32 "\n\r", id ) ;
+
+ /* Find triggering source */
+ i = 0;
+ while ( status != 0 )
+ {
+ /* There cannot be an unconfigured source enabled. */
+ assert(i < _dwNumSources);
+
+ /* Source is configured on the same controller */
+ if (_aIntSources[i].pPin->id == id)
+ {
+ /* Source has PIOs whose statuses have changed */
+ if ( (status & _aIntSources[i].pPin->mask) != 0 )
+ {
+ TRACE_DEBUG( "Interrupt source #%" PRIu32 " triggered\n\r", i ) ;
+
+ _aIntSources[i].handler(_aIntSources[i].pPin);
+ status &= ~(_aIntSources[i].pPin->mask);
+ }
+ }
+ i++;
+ }
+ }
+}
+
+/*----------------------------------------------------------------------------
+ * Global Functions
+ *----------------------------------------------------------------------------*/
+
+/**
+ * \brief Parallel IO Controller A interrupt handler
+ * \Redefined PIOA interrupt handler for NVIC interrupt table.
+ */
+extern void PIOA_IrqHandler( void )
+{
+ if ( PIOA->PIO_PCISR != 0 )
+ {
+ PIO_CaptureHandler() ;
+ }
+
+ PioInterruptHandler( ID_PIOA, PIOA ) ;
+}
+
+/**
+ * \brief Parallel IO Controller B interrupt handler
+ * \Redefined PIOB interrupt handler for NVIC interrupt table.
+ */
+extern void PIOB_IrqHandler( void )
+{
+ PioInterruptHandler( ID_PIOB, PIOB ) ;
+}
+
+/**
+ * \brief Parallel IO Controller C interrupt handler
+ * \Redefined PIOC interrupt handler for NVIC interrupt table.
+ */
+extern void PIOC_IrqHandler( void )
+{
+ PioInterruptHandler( ID_PIOC, PIOC ) ;
+}
+
+/**
+ * \brief Initializes the PIO interrupt management logic
+ *
+ * The desired priority of PIO interrupts must be provided.
+ * Calling this function multiple times result in the reset of currently
+ * configured interrupts.
+ *
+ * \param priority PIO controller interrupts priority.
+ */
+extern void PIO_InitializeInterrupts( uint32_t dwPriority )
+{
+ TRACE_DEBUG( "PIO_Initialize()\n\r" ) ;
+
+ /* Reset sources */
+ _dwNumSources = 0 ;
+
+ /* Configure PIO interrupt sources */
+ TRACE_DEBUG( "PIO_Initialize: Configuring PIOA\n\r" ) ;
+ PMC_EnablePeripheral( ID_PIOA ) ;
+ PIOA->PIO_ISR ;
+ PIOA->PIO_IDR = 0xFFFFFFFF ;
+ NVIC_DisableIRQ( PIOA_IRQn ) ;
+ NVIC_ClearPendingIRQ( PIOA_IRQn ) ;
+ NVIC_SetPriority( PIOA_IRQn, dwPriority ) ;
+ NVIC_EnableIRQ( PIOA_IRQn ) ;
+
+ TRACE_DEBUG( "PIO_Initialize: Configuring PIOB\n\r" ) ;
+ PMC_EnablePeripheral( ID_PIOB ) ;
+ PIOB->PIO_ISR ;
+ PIOB->PIO_IDR = 0xFFFFFFFF ;
+ NVIC_DisableIRQ( PIOB_IRQn ) ;
+ NVIC_ClearPendingIRQ( PIOB_IRQn ) ;
+ NVIC_SetPriority( PIOB_IRQn, dwPriority ) ;
+ NVIC_EnableIRQ( PIOB_IRQn ) ;
+
+ TRACE_DEBUG( "PIO_Initialize: Configuring PIOC\n\r" ) ;
+ PMC_EnablePeripheral( ID_PIOC ) ;
+ PIOC->PIO_ISR ;
+ PIOC->PIO_IDR = 0xFFFFFFFF ;
+ NVIC_DisableIRQ( PIOC_IRQn ) ;
+ NVIC_ClearPendingIRQ( PIOC_IRQn ) ;
+ NVIC_SetPriority( PIOC_IRQn, dwPriority ) ;
+ NVIC_EnableIRQ( PIOC_IRQn ) ;
+}
+
+/**
+ * Configures a PIO or a group of PIO to generate an interrupt on status
+ * change. The provided interrupt handler will be called with the triggering
+ * pin as its parameter (enabling different pin instances to share the same
+ * handler).
+ * \param pPin Pointer to a Pin instance.
+ * \param handler Interrupt handler function pointer.
+ */
+extern void PIO_ConfigureIt( const Pin *pPin, void (*handler)( const Pin* ) )
+{
+ Pio* pio ;
+ InterruptSource* pSource ;
+
+ TRACE_DEBUG( "PIO_ConfigureIt()\n\r" ) ;
+
+ assert( pPin ) ;
+ pio = pPin->pio ;
+ assert( _dwNumSources < MAX_INTERRUPT_SOURCES ) ;
+
+ /* Define new source */
+ TRACE_DEBUG( "PIO_ConfigureIt: Defining new source #%" PRIu32 ".\n\r", _dwNumSources ) ;
+
+ pSource = &(_aIntSources[_dwNumSources]) ;
+ pSource->pPin = pPin ;
+ pSource->handler = handler ;
+ _dwNumSources++ ;
+
+ /* PIO3 with additional interrupt support
+ * Configure additional interrupt mode registers */
+ if ( pPin->attribute & PIO_IT_AIME )
+ {
+ // enable additional interrupt mode
+ pio->PIO_AIMER = pPin->mask ;
+
+ // if bit field of selected pin is 1, set as Rising Edge/High level detection event
+ if ( pPin->attribute & PIO_IT_RE_OR_HL )
+ {
+ pio->PIO_REHLSR = pPin->mask ;
+ }
+ else
+ {
+ pio->PIO_FELLSR = pPin->mask;
+ }
+
+ /* if bit field of selected pin is 1, set as edge detection source */
+ if (pPin->attribute & PIO_IT_EDGE)
+ pio->PIO_ESR = pPin->mask;
+ else
+ pio->PIO_LSR = pPin->mask;
+ }
+ else
+ {
+ /* disable additional interrupt mode */
+ pio->PIO_AIMDR = pPin->mask;
+ }
+}
+
+/**
+ * Enables the given interrupt source if it has been configured. The status
+ * register of the corresponding PIO controller is cleared prior to enabling
+ * the interrupt.
+ * \param pPin Interrupt source to enable.
+ */
+extern void PIO_EnableIt( const Pin *pPin )
+{
+ TRACE_DEBUG( "PIO_EnableIt()\n\r" ) ;
+
+ assert( pPin != NULL ) ;
+
+#ifndef NOASSERT
+ uint32_t i = 0;
+ uint32_t dwFound = 0;
+
+ while ( (i < _dwNumSources) && !dwFound )
+ {
+ if ( _aIntSources[i].pPin == pPin )
+ {
+ dwFound = 1 ;
+ }
+ i++ ;
+ }
+ assert( dwFound != 0 ) ;
+#endif
+
+ pPin->pio->PIO_ISR;
+ pPin->pio->PIO_IER = pPin->mask ;
+}
+
+/**
+ * Disables a given interrupt source, with no added side effects.
+ *
+ * \param pPin Interrupt source to disable.
+ */
+extern void PIO_DisableIt( const Pin *pPin )
+{
+ assert( pPin != NULL ) ;
+
+ TRACE_DEBUG( "PIO_DisableIt()\n\r" ) ;
+
+ pPin->pio->PIO_IDR = pPin->mask;
+}
+