Changeset a4936b5 in rtems


Ignore:
Timestamp:
Dec 15, 2016, 1:55:45 PM (3 years ago)
Author:
Sebastian Huber <sebastian.huber@…>
Branches:
master
Children:
a5c56af
Parents:
8eb5fbb6
git-author:
Sebastian Huber <sebastian.huber@…> (12/15/16 13:55:45)
git-committer:
Sebastian Huber <sebastian.huber@…> (12/16/16 08:04:57)
Message:

bsp/atsam: System initialization for PIO IRQs

Location:
c/src/lib/libbsp
Files:
3 edited

Legend:

Unmodified
Added
Removed
  • c/src/lib/libbsp/arm/atsam/libraries/libchip/include/pio_it.h

    r8eb5fbb6 ra4936b5  
    7878extern void PIO_InitializeInterrupts(uint32_t dwPriority);
    7979
    80 extern void PIO_ConfigureIt(const Pin *pPin, void (*handler)(const Pin *));
     80extern void PIO_ConfigureIt(const Pin *pPin,
     81    void (*handler)(const Pin *, void *arg), void *arg);
    8182
    82 extern void PIO_EnableIt(const Pin *pPin);
    8383
    84 extern void PIO_DisableIt(const Pin *pPin);
     84/**
     85 * Enables the given interrupt source if it has been configured. The status
     86 * register of the corresponding PIO controller is cleared prior to enabling
     87 * the interrupt.
     88 * \param pPin  Interrupt source to enable.
     89 */
     90static inline void PIO_EnableIt(const Pin *pPin)
     91{
     92        pPin->pio->PIO_ISR;
     93        pPin->pio->PIO_IER = pPin->mask;
     94}
     95
     96/**
     97 * Disables a given interrupt source, with no added side effects.
     98 *
     99 * \param pPin  Interrupt source to disable.
     100 */
     101static inline void PIO_DisableIt(const Pin *pPin)
     102{
     103        pPin->pio->PIO_IDR = pPin->mask;
     104}
    85105
    86106extern void PIO_IT_InterruptHandler(void);
  • c/src/lib/libbsp/arm/atsam/libraries/libchip/source/pio_it.c

    r8eb5fbb6 ra4936b5  
    3838#include "chip.h"
    3939
    40 #include <assert.h>
     40#include <rtems/irq-extension.h>
     41#include <rtems/sysinit.h>
     42#include <bsp/fatal.h>
    4143
    4244/*----------------------------------------------------------------------------
     
    6264
    6365        /* Interrupt handler. */
    64         void (*handler)(const Pin *);
     66        void (*handler)(const Pin *, void *arg);
     67
     68        void *arg;
    6569} InterruptSource;
    6670
     
    8488 * \param pPio  PIO controller base address.
    8589 */
    86 extern void PioInterruptHandler(uint32_t id, Pio *pPio)
     90static void PIO_Interrupt(Pio *pPio, uint32_t id)
    8791{
    8892        uint32_t status;
    89         uint32_t i;
    90 
    91         /* Read PIO controller status */
     93        size_t i;
     94
    9295        status = pPio->PIO_ISR;
    9396        status &= pPio->PIO_IMR;
    9497
    95         /* Check pending events */
    96         if (status != 0) {
    97                 TRACE_DEBUG("PIO interrupt on PIO controller #%d\n\r", id);
    98 
    99                 /* Find triggering source */
    100                 i = 0;
    101 
    102                 while (status != 0) {
    103                         /* There cannot be an un-configured source enabled. */
    104                         assert(i < _dwNumSources);
    105 
    106                         /* Source is configured on the same controller */
    107                         if (_aIntSources[i].pPin->id == id) {
    108                                 /* Source has PIOs whose statuses have changed */
    109                                 if ((status & _aIntSources[i].pPin->mask) != 0) {
    110                                         TRACE_DEBUG("Interrupt source #%d triggered\n\r", i);
    111                                         _aIntSources[i].handler(_aIntSources[i].pPin);
    112                                         status &= ~(_aIntSources[i].pPin->mask);
    113                                 }
     98        for (i = 0; status != 0 && i < MAX_INTERRUPT_SOURCES; ++i) {
     99                const InterruptSource *is = &_aIntSources[i];
     100                const Pin *pin = is->pPin;;
     101
     102                if (pin->id == id) {
     103                        uint32_t mask = pin->mask;
     104
     105                        if ((status & mask) != 0) {
     106                                status &= ~mask;
     107                                (*is->handler)(pin, is->arg);
    114108                        }
    115 
    116                         i++;
    117109                }
    118110        }
     
    127119 * \Redefined PIOA interrupt handler for NVIC interrupt table.
    128120 */
    129 extern void PIOA_Handler(void)
    130 {
    131         PioInterruptHandler(ID_PIOA, PIOA);
     121static void PIOA_Interrupt(void *arg)
     122{
     123        PIO_Interrupt(arg, ID_PIOA);
    132124}
    133125
     
    136128 * \Redefined PIOB interrupt handler for NVIC interrupt table.
    137129 */
    138 extern void PIOB_Handler(void)
    139 {
    140         PioInterruptHandler(ID_PIOB, PIOB);
     130static void PIOB_Interrupt(void *arg)
     131{
     132        PIO_Interrupt(arg, ID_PIOB);
    141133}
    142134
     
    145137 * \Redefined PIOC interrupt handler for NVIC interrupt table.
    146138 */
    147 extern void PIOC_Handler(void)
    148 {
    149         PioInterruptHandler(ID_PIOC, PIOC);
     139static void PIOC_Interrupt(void *arg)
     140{
     141        PIO_Interrupt(arg, ID_PIOC);
    150142}
    151143
     
    155147 * \Redefined PIOD interrupt handler for NVIC interrupt table.
    156148 */
    157 extern void PIOD_Handler(void)
    158 {
    159         PioInterruptHandler(ID_PIOD, PIOD);
     149static void PIOD_Interrupt(void *arg)
     150{
     151        PIO_Interrupt(arg, ID_PIOD);
    160152}
    161153
     
    164156 * \Redefined PIOE interrupt handler for NVIC interrupt table.
    165157 */
    166 extern void PIOE_Handler(void)
    167 {
    168         PioInterruptHandler(ID_PIOE, PIOE);
    169 }
    170 
    171 /**
    172  * \brief Initializes the PIO interrupt management logic
    173  *
    174  * The desired priority of PIO interrupts must be provided.
    175  * Calling this function multiple times result in the reset of currently
    176  * configured interrupts.
    177  *
    178  * \param priority  PIO controller interrupts priority.
    179  */
    180 extern void PIO_InitializeInterrupts(uint32_t dwPriority)
    181 {
     158static void PIOE_Interrupt(void *arg)
     159{
     160        PIO_Interrupt(arg, ID_PIOE);
     161}
     162
     163static void PIO_SysInitializeInterrupts(void)
     164{
     165        rtems_status_code sc;
     166
    182167        TRACE_DEBUG("PIO_Initialize()\n\r");
    183 
    184         /* Reset sources */
    185         _dwNumSources = 0;
    186168
    187169        /* Configure PIO interrupt sources */
     
    190172        PIOA->PIO_ISR;
    191173        PIOA->PIO_IDR = 0xFFFFFFFF;
    192         NVIC_DisableIRQ(PIOA_IRQn);
    193         NVIC_ClearPendingIRQ(PIOA_IRQn);
    194         NVIC_SetPriority(PIOA_IRQn, dwPriority);
    195         NVIC_EnableIRQ(PIOA_IRQn);
     174        sc = rtems_interrupt_handler_install(
     175                PIOA_IRQn,
     176                "PIO A",
     177                RTEMS_INTERRUPT_UNIQUE,
     178                PIOA_Interrupt,
     179                PIOA
     180        );
     181        if (sc != RTEMS_SUCCESSFUL) {
     182                bsp_fatal(ATSAM_FATAL_PIO_IRQ_A);
     183        }
    196184
    197185        TRACE_DEBUG("PIO_Initialize: Configuring PIOB\n\r");
     
    199187        PIOB->PIO_ISR;
    200188        PIOB->PIO_IDR = 0xFFFFFFFF;
    201         NVIC_DisableIRQ(PIOB_IRQn);
    202         NVIC_ClearPendingIRQ(PIOB_IRQn);
    203         NVIC_SetPriority(PIOB_IRQn, dwPriority);
    204         NVIC_EnableIRQ(PIOB_IRQn);
     189        sc = rtems_interrupt_handler_install(
     190                PIOB_IRQn,
     191                "PIO B",
     192                RTEMS_INTERRUPT_UNIQUE,
     193                PIOB_Interrupt,
     194                PIOB
     195        );
     196        if (sc != RTEMS_SUCCESSFUL) {
     197                bsp_fatal(ATSAM_FATAL_PIO_IRQ_B);
     198        }
    205199
    206200        TRACE_DEBUG("PIO_Initialize: Configuring PIOC\n\r");
     
    208202        PIOC->PIO_ISR;
    209203        PIOC->PIO_IDR = 0xFFFFFFFF;
    210         NVIC_DisableIRQ(PIOC_IRQn);
    211         NVIC_ClearPendingIRQ(PIOC_IRQn);
    212         NVIC_SetPriority(PIOC_IRQn, dwPriority);
    213         NVIC_EnableIRQ(PIOC_IRQn);
     204        sc = rtems_interrupt_handler_install(
     205                PIOC_IRQn,
     206                "PIO C",
     207                RTEMS_INTERRUPT_UNIQUE,
     208                PIOC_Interrupt,
     209                PIOC
     210        );
     211        if (sc != RTEMS_SUCCESSFUL) {
     212                bsp_fatal(ATSAM_FATAL_PIO_IRQ_C);
     213        }
    214214
    215215        TRACE_DEBUG("PIO_Initialize: Configuring PIOD\n\r");
     
    217217        PIOD->PIO_ISR;
    218218        PIOD->PIO_IDR = 0xFFFFFFFF;
    219         NVIC_DisableIRQ(PIOD_IRQn);
    220         NVIC_ClearPendingIRQ(PIOD_IRQn);
    221         NVIC_SetPriority(PIOD_IRQn, dwPriority);
    222         NVIC_EnableIRQ(PIOD_IRQn);
     219        sc = rtems_interrupt_handler_install(
     220                PIOD_IRQn,
     221                "PIO D",
     222                RTEMS_INTERRUPT_UNIQUE,
     223                PIOD_Interrupt,
     224                PIOD
     225        );
     226        if (sc != RTEMS_SUCCESSFUL) {
     227                bsp_fatal(ATSAM_FATAL_PIO_IRQ_D);
     228        }
    223229
    224230        TRACE_DEBUG("PIO_Initialize: Configuring PIOE\n\r");
     
    226232        PIOE->PIO_ISR;
    227233        PIOE->PIO_IDR = 0xFFFFFFFF;
    228         NVIC_DisableIRQ(PIOE_IRQn);
    229         NVIC_ClearPendingIRQ(PIOE_IRQn);
    230         NVIC_SetPriority(PIOE_IRQn, dwPriority);
    231         NVIC_EnableIRQ(PIOE_IRQn);
    232 }
     234        sc = rtems_interrupt_handler_install(
     235                PIOE_IRQn,
     236                "PIO E",
     237                RTEMS_INTERRUPT_UNIQUE,
     238                PIOE_Interrupt,
     239                PIOE
     240        );
     241        if (sc != RTEMS_SUCCESSFUL) {
     242                bsp_fatal(ATSAM_FATAL_PIO_IRQ_E);
     243        }
     244}
     245
     246RTEMS_SYSINIT_ITEM(PIO_SysInitializeInterrupts, RTEMS_SYSINIT_BSP_START,
     247    RTEMS_SYSINIT_ORDER_LAST);
    233248
    234249/**
     
    240255 * \param handler  Interrupt handler function pointer.
    241256 */
    242 extern void PIO_ConfigureIt(const Pin *pPin, void (*handler)(const Pin *))
     257void PIO_ConfigureIt(const Pin *pPin, void (*handler)(const Pin *, void *arg),
     258    void *arg)
    243259{
    244260        Pio *pio;
    245261        InterruptSource *pSource;
     262        rtems_interrupt_level level;
    246263
    247264        TRACE_DEBUG("PIO_ConfigureIt()\n\r");
    248265
    249         assert(pPin);
    250266        pio = pPin->pio;
    251         assert(_dwNumSources < MAX_INTERRUPT_SOURCES);
    252 
    253         /* Define new source */
    254         TRACE_DEBUG("PIO_ConfigureIt: Defining new source #%d.\n\r", _dwNumSources);
     267
     268        rtems_interrupt_disable(level);
     269
     270        if (_dwNumSources == MAX_INTERRUPT_SOURCES) {
     271                bsp_fatal(ATSAM_FATAL_PIO_CONFIGURE_IT);
     272        }
    255273
    256274        pSource = &(_aIntSources[_dwNumSources]);
     
    258276        pSource->handler = handler;
    259277        _dwNumSources++;
     278
     279        rtems_interrupt_enable(level);
     280
     281        /* Define new source */
     282        TRACE_DEBUG("PIO_ConfigureIt: Defining new source #%d.\n\r", _dwNumSources);
    260283
    261284        /* PIO3 with additional interrupt support
     
    281304        }
    282305}
    283 
    284 /**
    285  * Enables the given interrupt source if it has been configured. The status
    286  * register of the corresponding PIO controller is cleared prior to enabling
    287  * the interrupt.
    288  * \param pPin  Interrupt source to enable.
    289  */
    290 extern void PIO_EnableIt(const Pin *pPin)
    291 {
    292         uint32_t i = 0;
    293         uint32_t dwFound = 0;
    294 
    295         TRACE_DEBUG("PIO_EnableIt()\n\r");
    296 
    297         assert(pPin != NULL);
    298 
    299 #ifndef NOASSERT
    300 
    301         while ((i < _dwNumSources) && !dwFound) {
    302                 if (_aIntSources[i].pPin == pPin)
    303                         dwFound = 1;
    304 
    305                 i++;
    306         }
    307 
    308         assert(dwFound != 0);
    309 #endif
    310 
    311         pPin->pio->PIO_ISR;
    312         pPin->pio->PIO_IER = pPin->mask;
    313 }
    314 
    315 /**
    316  * Disables a given interrupt source, with no added side effects.
    317  *
    318  * \param pPin  Interrupt source to disable.
    319  */
    320 extern void PIO_DisableIt(const Pin *pPin)
    321 {
    322         assert(pPin != NULL);
    323 
    324         TRACE_DEBUG("PIO_DisableIt()\n\r");
    325 
    326         pPin->pio->PIO_IDR = pPin->mask;
    327 }
    328 
  • c/src/lib/libbsp/shared/include/fatal.h

    r8eb5fbb6 ra4936b5  
    128128
    129129  /* ATSAM fatal codes */
    130   ATSAM_FATAL_XDMA_IRQ_INSTALL = BSP_FATAL_CODE_BLOCK(11)
     130  ATSAM_FATAL_XDMA_IRQ_INSTALL = BSP_FATAL_CODE_BLOCK(11),
     131  ATSAM_FATAL_PIO_IRQ_A,
     132  ATSAM_FATAL_PIO_IRQ_B,
     133  ATSAM_FATAL_PIO_IRQ_C,
     134  ATSAM_FATAL_PIO_IRQ_D,
     135  ATSAM_FATAL_PIO_IRQ_E,
     136  ATSAM_FATAL_PIO_CONFIGURE_IT
    131137} bsp_fatal_code;
    132138
Note: See TracChangeset for help on using the changeset viewer.