예제 #1
0
파일: gpio_irq_api.c 프로젝트: yanesca/mbed
static void gpio_irq(struct nu_gpio_irq_var *var)
{
    uint32_t port_index = var->irq_n - GPA_IRQn;
    GPIO_T *gpio_base = NU_PORT_BASE(port_index);
    
    uint32_t intsrc = gpio_base->INTSRC;
    uint32_t inten = gpio_base->INTEN;
    while (intsrc) {
        int pin_index = nu_ctz(intsrc);
        gpio_irq_t *obj = var->obj_arr[pin_index];
        if (inten & (GPIO_INT_RISING << pin_index)) {
            if (GPIO_PIN_ADDR(port_index, pin_index)) {
                if (obj->irq_handler) {
                    ((gpio_irq_handler) obj->irq_handler)(obj->irq_id, IRQ_RISE);
                }
            }
        }
        
        if (inten & (GPIO_INT_FALLING << pin_index)) {   
            if (! GPIO_PIN_ADDR(port_index, pin_index)) {
                if (obj->irq_handler) {
                    ((gpio_irq_handler) obj->irq_handler)(obj->irq_id, IRQ_FALL);
                }
            }
        }
        
        intsrc &= ~(1 << pin_index);
    }
    // Clear all interrupt flags
    gpio_base->INTSRC = gpio_base->INTSRC;
}
예제 #2
0
파일: dma_api.c 프로젝트: akselsm/mbed
static void pdma_vec(void)
{
    uint32_t intsts = PDMA_GET_INT_STATUS();
    
    // Abort
    if (intsts & PDMA_INTSTS_ABTIF_Msk) {
        uint32_t abtsts = PDMA_GET_ABORT_STS();
        // Clear all Abort flags
        PDMA_CLR_ABORT_FLAG(abtsts);
        
        while (abtsts) {
            int chn_id = nu_ctz(abtsts);
            if (dma_chn_mask & (1 << chn_id)) {
                struct nu_dma_chn_s *dma_chn = dma_chn_arr + chn_id;
                if (dma_chn->handler && (dma_chn->event & DMA_EVENT_ABORT)) {
                    dma_chn->handler(dma_chn->id, DMA_EVENT_ABORT);
                }
            }
            abtsts &= ~(1 << chn_id);
        }
    }
    
    // Transfer done
    if (intsts & PDMA_INTSTS_TDIF_Msk) {
        uint32_t tdsts = PDMA_GET_TD_STS();    
        // Clear all transfer done flags
        PDMA_CLR_TD_FLAG(tdsts);
        
        while (tdsts) {
            int chn_id = nu_ctz(tdsts);
            if (dma_chn_mask & (1 << chn_id)) {
                struct nu_dma_chn_s *dma_chn = dma_chn_arr + chn_id;
                if (dma_chn->handler && (dma_chn->event & DMA_EVENT_TRANSFER_DONE)) {
                    dma_chn->handler(dma_chn->id, DMA_EVENT_TRANSFER_DONE);
                }
            }
            tdsts &= ~(1 << chn_id);
        }
    }
    
    // Table empty
    if (intsts & PDMA_INTSTS_TEIF_Msk) {
        uint32_t scatsts = PDMA_GET_EMPTY_STS();    
        // Clear all table empty flags
        PDMA_CLR_EMPTY_FLAG(scatsts);
    }
    
    // Timeout
    uint32_t reqto = intsts & PDMA_INTSTS_REQTOFn_Msk;
    if (reqto) {
        // Clear all Timeout flags
        PDMA->INTSTS = reqto;
        
        while (reqto) {
            int chn_id = nu_ctz(reqto) - PDMA_INTSTS_REQTOFn_Pos;
            if (dma_chn_mask & (1 << chn_id)) {
                struct nu_dma_chn_s *dma_chn = dma_chn_arr + chn_id;
                if (dma_chn->handler && (dma_chn->event & DMA_EVENT_TIMEOUT)) {
                    dma_chn->handler(dma_chn->id, DMA_EVENT_TIMEOUT);
                }
            }
            reqto &= ~(1 << (chn_id + PDMA_INTSTS_REQTOFn_Pos));
        }
    }
}