Fix some bugs about IntreruptIn.

Bugs are as below.
- Add terminal setting of IRQ4 and IRQ6 that leaked.
- When set the interrupt function by rise()/fall(), the interrupt disable state will be released by disable_irq().
- Interrupt will be continued to occur when execute disable_irq() after rise(NULL)/fall(NULL) set.
- Fix the setting timing of PMC register.
pull/835/head
Masao Hamanaka 2015-01-07 19:11:14 +09:00
parent f119a368e5
commit 90cf47ffdf
3 changed files with 31 additions and 21 deletions

View File

@ -58,27 +58,28 @@ static const IRQHandler irq_tbl[CHANNEL_NUM] = {
static const PinMap PinMap_IRQ[] = { static const PinMap PinMap_IRQ[] = {
{P1_0, IRQ0, 4}, {P1_1, IRQ1, 4}, {P1_2, IRQ2, 4}, {P1_0, IRQ0, 4}, {P1_1, IRQ1, 4}, {P1_2, IRQ2, 4},
{P1_3, IRQ3, 4}, {P1_5, IRQ5, 4}, {P1_7, IRQ7, 4}, {P1_3, IRQ3, 4}, {P1_4, IRQ4, 4}, {P1_5, IRQ5, 4},
{P1_8, IRQ2, 3}, {P1_9, IRQ3, 3}, {P1_10, IRQ4, 3}, {P1_6, IRQ6, 4}, {P1_7, IRQ7, 4}, {P1_8, IRQ2, 3},
{P1_11, IRQ5, 3}, // 9 {P1_9, IRQ3, 3}, {P1_10, IRQ4, 3}, {P1_11, IRQ5, 3}, // 11
{P2_0, IRQ5, 6}, {P2_13, IRQ7, 8}, {P2_14, IRQ0, 8}, {P2_0, IRQ5, 6}, {P2_12, IRQ6, 6}, {P2_13, IRQ7, 8},
{P2_15, IRQ1, 8}, // 13 {P2_14, IRQ0, 8}, {P2_15, IRQ1, 8}, // 16
{P3_0, IRQ2, 3}, {P3_3, IRQ4, 3}, // 15 {P3_0, IRQ2, 3}, {P3_1, IRQ6, 3}, {P3_3, IRQ4, 3},
{P3_9, IRQ6, 8}, // 20
{P4_8, IRQ0, 8}, {P4_9, IRQ1, 8}, {P4_10, IRQ2, 8}, {P4_8, IRQ0, 8}, {P4_9, IRQ1, 8}, {P4_10, IRQ2, 8},
{P4_11, IRQ3, 8}, {P4_12, IRQ4, 8}, {P4_13, IRQ5, 8}, {P4_11, IRQ3, 8}, {P4_12, IRQ4, 8}, {P4_13, IRQ5, 8},
{P4_14, IRQ6, 8}, {P4_15, IRQ7, 8}, // 23 {P4_14, IRQ6, 8}, {P4_15, IRQ7, 8}, // 28
{P5_6, IRQ6, 6}, {P5_8, IRQ0, 2}, {P5_9, IRQ2, 4}, // 26 {P5_6, IRQ6, 6}, {P5_8, IRQ0, 2}, {P5_9, IRQ2, 4}, // 31
{P6_0, IRQ5, 6}, {P6_1, IRQ4, 4}, {P6_2, IRQ7, 4}, {P6_0, IRQ5, 6}, {P6_1, IRQ4, 4}, {P6_2, IRQ7, 4},
{P6_3, IRQ2, 4}, {P6_4, IRQ3, 4}, {P6_8, IRQ0, 8}, {P6_3, IRQ2, 4}, {P6_4, IRQ3, 4}, {P6_8, IRQ0, 8},
{P6_9, IRQ1, 8}, {P6_10, IRQ2, 8}, {P6_11, IRQ3, 8}, {P6_9, IRQ1, 8}, {P6_10, IRQ2, 8}, {P6_11, IRQ3, 8},
{P6_12, IRQ4, 8}, {P6_13, IRQ5, 8}, {P6_14, IRQ6, 8}, {P6_12, IRQ4, 8}, {P6_13, IRQ5, 8}, {P6_14, IRQ6, 8},
{P6_15, IRQ7, 8}, // 39 {P6_15, IRQ7, 8}, // 44
{P7_8, IRQ1, 8}, {P7_9, IRQ0, 8}, {P7_10, IRQ2, 8}, {P7_8, IRQ1, 8}, {P7_9, IRQ0, 8}, {P7_10, IRQ2, 8},
{P7_11, IRQ3, 8}, {P7_12, IRQ4, 8}, {P7_13, IRQ5, 8}, {P7_11, IRQ3, 8}, {P7_12, IRQ4, 8}, {P7_13, IRQ5, 8},
{P7_14, IRQ6, 8}, // 46 {P7_14, IRQ6, 8}, // 51
{P8_2, IRQ0, 5}, {P8_3, IRQ1, 6}, {P8_7, IRQ5, 4}, {P8_2, IRQ0, 5}, {P8_3, IRQ1, 6}, {P8_7, IRQ5, 4},
{P9_1, IRQ0, 4}, // 50 {P9_1, IRQ0, 4}, // 55
{P11_12,IRQ3, 3}, {P11_15,IRQ1, 3}, // 52 {P11_12,IRQ3, 3}, {P11_15,IRQ1, 3}, // 57
{NC, NC, 0} {NC, NC, 0}
}; };
@ -167,6 +168,7 @@ int gpio_irq_init(gpio_irq_t *obj, PinName pin, gpio_irq_handler handler, uint32
INTCICR1 |= (0x3 << shift); INTCICR1 |= (0x3 << shift);
GIC_SetPriority((IRQn_Type)(nIRQn_h+obj->ch), 5); GIC_SetPriority((IRQn_Type)(nIRQn_h+obj->ch), 5);
GIC_EnableIRQ((IRQn_Type)(nIRQn_h+obj->ch)); GIC_EnableIRQ((IRQn_Type)(nIRQn_h+obj->ch));
obj->int_enable = 1;
__enable_irq(); __enable_irq();
return 0; return 0;
@ -181,8 +183,7 @@ void gpio_irq_set(gpio_irq_t *obj, gpio_irq_event event, uint32_t enable) {
uint16_t val = event == IRQ_RISE ? 2 : uint16_t val = event == IRQ_RISE ? 2 :
event == IRQ_FALL ? 1 : 0; event == IRQ_FALL ? 1 : 0;
uint16_t work_icr_val; uint16_t work_icr_val;
uint16_t work_irqrr_val;
/* check edge interrupt setting */ /* check edge interrupt setting */
work_icr_val = INTCICR1; work_icr_val = INTCICR1;
if (enable == 1) { if (enable == 1) {
@ -192,25 +193,33 @@ void gpio_irq_set(gpio_irq_t *obj, gpio_irq_event event, uint32_t enable) {
/* Clear interrupt serect */ /* Clear interrupt serect */
work_icr_val &= ~(val << shift); work_icr_val &= ~(val << shift);
} }
if ((work_icr_val & (3 << shift)) == 0) { if ((work_icr_val & (3 << shift)) == 0) {
/* No edge interrupt setting */ /* No edge interrupt setting */
GIC_DisableIRQ((IRQn_Type)(nIRQn_h+obj->ch)); GIC_DisableIRQ((IRQn_Type)(nIRQn_h+obj->ch));
/* Clear Interrupt flags */ /* Clear Interrupt flags */
work_irqrr_val = INTCIRQRR; INTCIRQRR &= ~(1 << obj->ch);
INTCIRQRR = (work_irqrr_val & ~(1 << obj->ch)); } else if (obj->int_enable == 1) {
GIC_EnableIRQ((IRQn_Type)(nIRQn_h + obj->ch));
} else { } else {
/* Edge interrupt setting */ /* Do Nothing */
GIC_EnableIRQ((IRQn_Type)(nIRQn_h+obj->ch));
} }
INTCICR1 = work_icr_val; INTCICR1 = work_icr_val;
} }
void gpio_irq_enable(gpio_irq_t *obj) { void gpio_irq_enable(gpio_irq_t *obj) {
GIC_EnableIRQ((IRQn_Type)(nIRQn_h + obj->ch)); int shift = obj->ch*2;
uint16_t work_icr_val = INTCICR1;
/* check edge interrupt setting */
if ((work_icr_val & (3 << shift)) != 0) {
GIC_EnableIRQ((IRQn_Type)(nIRQn_h + obj->ch));
}
obj->int_enable = 1;
} }
void gpio_irq_disable(gpio_irq_t *obj) { void gpio_irq_disable(gpio_irq_t *obj) {
GIC_DisableIRQ((IRQn_Type)(nIRQn_h + obj->ch)); GIC_DisableIRQ((IRQn_Type)(nIRQn_h + obj->ch));
obj->int_enable = 0;
} }

View File

@ -46,6 +46,7 @@ struct gpio_irq_s {
uint32_t port; uint32_t port;
uint32_t pin; uint32_t pin;
uint32_t ch; uint32_t ch;
uint8_t int_enable;
}; };
struct port_s { struct port_s {

View File

@ -31,7 +31,6 @@ void pin_function(PinName pin, int function) {
*PMC(n) &= ~bitmask; *PMC(n) &= ~bitmask;
} else { } else {
// alt-function mode // alt-function mode
*PMC(n) |= bitmask;
--function; --function;
if (function & (1 << 2)) { *PFCAE(n) |= bitmask;}else { *PFCAE(n) &= ~bitmask;} if (function & (1 << 2)) { *PFCAE(n) |= bitmask;}else { *PFCAE(n) &= ~bitmask;}
@ -42,6 +41,7 @@ void pin_function(PinName pin, int function) {
if (P1_0 <= pin && pin <= P1_7 && function == 0) { if (P1_0 <= pin && pin <= P1_7 && function == 0) {
*PBDC(n) |= bitmask; *PBDC(n) |= bitmask;
} }
*PMC(n) |= bitmask;
} }
} else { } else {
gpio_multi_guard = (PinName)NC; gpio_multi_guard = (PinName)NC;