diff --git a/bsp/at91sam9260/at91_mci.c b/bsp/at91sam9260/at91_mci.c index 51a63c9613..90d002d2bc 100644 --- a/bsp/at91sam9260/at91_mci.c +++ b/bsp/at91sam9260/at91_mci.c @@ -49,8 +49,6 @@ struct at91_mci { rt_uint32_t current_status; }; -static struct at91_mci *at_mci; - /* * Reset the controller and restore most of the state */ @@ -592,8 +590,9 @@ static void at91_mci_completed_command(struct at91_mci *mci, rt_uint32_t status) /* * Handle an interrupt */ -static void at91_mci_irq(int irq) +static void at91_mci_irq(int irq, void *param) { + struct at91_mci *mci = (struct at91_mci *)param; rt_int32_t completed = 0; rt_uint32_t int_status, int_mask; @@ -635,13 +634,13 @@ static void at91_mci_irq(int irq) if (int_status & AT91_MCI_TXBUFE) { mci_dbg("TX buffer empty\n"); - at91_mci_handle_transmitted(at_mci); + at91_mci_handle_transmitted(mci); } if (int_status & AT91_MCI_ENDRX) { mci_dbg("ENDRX\n"); - at91_mci_post_dma_read(at_mci); + at91_mci_post_dma_read(mci); } if (int_status & AT91_MCI_RXBUFF) @@ -668,7 +667,7 @@ static void at91_mci_irq(int irq) if (int_status & AT91_MCI_BLKE) { mci_dbg("Block transfer has ended\n"); - if (at_mci->req->data && at_mci->req->data->blks > 1) + if (mci->req->data && mci->req->data->blks > 1) { /* multi block write : complete multi write * command and send stop */ @@ -684,7 +683,7 @@ static void at91_mci_irq(int irq) rt_mmcsd_signal_sdio_irq(host->mmc);*/ if (int_status & AT91_MCI_SDIOIRQB) - sdio_irq_wakeup(at_mci->host); + sdio_irq_wakeup(mci->host); if (int_status & AT91_MCI_TXRDY) mci_dbg("Ready to transmit\n"); @@ -695,7 +694,7 @@ static void at91_mci_irq(int irq) if (int_status & AT91_MCI_CMDRDY) { mci_dbg("Command ready\n"); - completed = at91_mci_handle_cmdrdy(at_mci); + completed = at91_mci_handle_cmdrdy(mci); } } @@ -703,7 +702,7 @@ static void at91_mci_irq(int irq) { mci_dbg("Completed command\n"); at91_mci_write(AT91_MCI_IDR, 0xffffffff & ~(AT91_MCI_SDIOIRQA | AT91_MCI_SDIOIRQB)); - at91_mci_completed_command(at_mci, int_status); + at91_mci_completed_command(mci, int_status); } else at91_mci_write(AT91_MCI_IDR, int_status & ~(AT91_MCI_SDIOIRQA | AT91_MCI_SDIOIRQB)); @@ -791,7 +790,7 @@ static const struct rt_mmcsd_host_ops ops = { at91_mci_enable_sdio_irq, }; -void at91_mci_detect(int irq) +void at91_mci_detect(int irq, void *param) { rt_kprintf("mmcsd gpio detected\n"); } @@ -819,7 +818,7 @@ static void mci_gpio_init() rt_int32_t at91_mci_init(void) { struct rt_mmcsd_host *host; - //struct at91_mci *mci; + struct at91_mci *mci; host = mmcsd_alloc_host(); if (!host) @@ -827,14 +826,14 @@ rt_int32_t at91_mci_init(void) return -RT_ERROR; } - at_mci = rt_malloc(sizeof(struct at91_mci)); - if (!at_mci) + mci = rt_malloc(sizeof(struct at91_mci)); + if (!mci) { rt_kprintf("alloc mci failed\n"); goto err; } - rt_memset(at_mci, 0, sizeof(struct at91_mci)); + rt_memset(mci, 0, sizeof(struct at91_mci)); host->ops = &ops; host->freq_min = 375000; @@ -846,7 +845,7 @@ rt_int32_t at91_mci_init(void) host->max_blk_size = 512; host->max_blk_count = 4096; - at_mci->host = host; + mci->host = host; mci_gpio_init(); at91_sys_write(AT91_PMC_PCER, 1 << AT91SAM9260_ID_MCI); //enable MCI clock @@ -855,14 +854,16 @@ rt_int32_t at91_mci_init(void) at91_mci_enable(); /* instal interrupt */ - rt_hw_interrupt_install(AT91SAM9260_ID_MCI, at91_mci_irq, RT_NULL); + rt_hw_interrupt_install(AT91SAM9260_ID_MCI, at91_mci_irq, + (void *)mci, "MMC"); rt_hw_interrupt_umask(AT91SAM9260_ID_MCI); - rt_hw_interrupt_install(gpio_to_irq(AT91_PIN_PA7), at91_mci_detect, RT_NULL); + rt_hw_interrupt_install(gpio_to_irq(AT91_PIN_PA7), + at91_mci_detect, RT_NULL, "MMC_DETECT"); rt_hw_interrupt_umask(gpio_to_irq(AT91_PIN_PA7)); - rt_timer_init(&at_mci->timer, "mci_timer", + rt_timer_init(&mci->timer, "mci_timer", at91_timeout_timer, - at_mci, + mci, RT_TICK_PER_SECOND, RT_TIMER_FLAG_PERIODIC); @@ -870,7 +871,7 @@ rt_int32_t at91_mci_init(void) //rt_sem_init(&mci->sem_ack, "sd_ack", 0, RT_IPC_FLAG_FIFO); - host->private_data = at_mci; + host->private_data = mci; mmcsd_change(host); diff --git a/bsp/at91sam9260/board.c b/bsp/at91sam9260/board.c index ac587e91ed..8b098a7f0e 100755 --- a/bsp/at91sam9260/board.c +++ b/bsp/at91sam9260/board.c @@ -92,9 +92,10 @@ struct rt_device uart4_device; /** * This function will handle serial */ -void rt_serial_handler(int vector) +void rt_serial_handler(int vector, void *param) { int status; + struct rt_device *dev = (rt_device_t)param; switch (vector) { @@ -105,7 +106,7 @@ void rt_serial_handler(int vector) { return; } - rt_hw_serial_isr(&uart1_device); + rt_hw_serial_isr(dev); break; #endif #ifdef RT_USING_UART1 @@ -115,7 +116,7 @@ void rt_serial_handler(int vector) { return; } - rt_hw_serial_isr(&uart2_device); + rt_hw_serial_isr(dev); break; #endif #ifdef RT_USING_UART2 @@ -125,7 +126,7 @@ void rt_serial_handler(int vector) { return; } - rt_hw_serial_isr(&uart3_device); + rt_hw_serial_isr(dev); break; #endif #ifdef RT_USING_UART3 @@ -135,7 +136,7 @@ void rt_serial_handler(int vector) { return; } - rt_hw_serial_isr(&uart4_device); + rt_hw_serial_isr(dev); break; #endif default: break; @@ -176,7 +177,8 @@ void rt_hw_uart_init(void) at91_sys_write(AT91_PIOB + PIO_PDR, (1<<4)|(1<<5)); uart_port_init(AT91SAM9260_BASE_US0); /* install interrupt handler */ - rt_hw_interrupt_install(AT91SAM9260_ID_US0, rt_serial_handler, RT_NULL); + rt_hw_interrupt_install(AT91SAM9260_ID_US0, rt_serial_handler, + (void *)&uart1_device, "UART0"); rt_hw_interrupt_umask(AT91SAM9260_ID_US0); #endif #ifdef RT_USING_UART1 @@ -188,7 +190,8 @@ void rt_hw_uart_init(void) at91_sys_write(AT91_PIOB + PIO_PDR, (1<<6)|(1<<7)); uart_port_init(AT91SAM9260_BASE_US1); /* install interrupt handler */ - rt_hw_interrupt_install(AT91SAM9260_ID_US1, rt_serial_handler, RT_NULL); + rt_hw_interrupt_install(AT91SAM9260_ID_US1, rt_serial_handler, + (void *)&uart2_device, "UART1"); rt_hw_interrupt_umask(AT91SAM9260_ID_US1); #endif #ifdef RT_USING_UART2 @@ -200,7 +203,8 @@ void rt_hw_uart_init(void) at91_sys_write(AT91_PIOB + PIO_PDR, (1<<8)|(1<<9)); uart_port_init(AT91SAM9260_BASE_US2); /* install interrupt handler */ - rt_hw_interrupt_install(AT91SAM9260_ID_US2, rt_serial_handler, RT_NULL); + rt_hw_interrupt_install(AT91SAM9260_ID_US2, rt_serial_handler, + (void *)&uart3_device, "UART2"); rt_hw_interrupt_umask(AT91SAM9260_ID_US2); #endif #ifdef RT_USING_UART3 @@ -212,7 +216,8 @@ void rt_hw_uart_init(void) at91_sys_write(AT91_PIOB + PIO_PDR, (1<<10)|(1<<11)); uart_port_init(AT91SAM9260_BASE_US3); /* install interrupt handler */ - rt_hw_interrupt_install(AT91SAM9260_ID_US3, rt_serial_handler, RT_NULL); + rt_hw_interrupt_install(AT91SAM9260_ID_US3, rt_serial_handler, + (void *)&uart4_device, "UART3"); rt_hw_interrupt_umask(AT91SAM9260_ID_US3); #endif @@ -246,7 +251,7 @@ static rt_uint32_t pit_cnt; /* access only w/system irq blocked */ /** * This function will handle rtos timer */ -void rt_timer_handler(int vector) +void rt_timer_handler(int vector, void *param) { #ifdef RT_USING_DBGU if (at91_sys_read(AT91_DBGU + AT91_US_CSR) & 0x1) { @@ -309,7 +314,8 @@ static void at91sam926x_pit_init(void) at91sam926x_pit_init(); /* install interrupt handler */ - rt_hw_interrupt_install(AT91_ID_SYS, rt_timer_handler, RT_NULL); + rt_hw_interrupt_install(AT91_ID_SYS, rt_timer_handler, + RT_NULL, "system"); rt_hw_interrupt_umask(AT91_ID_SYS); } diff --git a/bsp/at91sam9260/macb.c b/bsp/at91sam9260/macb.c index 9f545aa8f2..e4371ec55d 100755 --- a/bsp/at91sam9260/macb.c +++ b/bsp/at91sam9260/macb.c @@ -103,9 +103,9 @@ static void udelay(rt_uint32_t us) for (len = 0; len < 10; len++ ); } -static void rt_macb_isr(int irq) +static void rt_macb_isr(int irq, void *param) { - struct rt_macb_eth *macb = &macb_device; + struct rt_macb_eth *macb = (struct rt_macb_eth *)param; rt_device_t dev = &(macb->parent.parent); rt_uint32_t status, rsr, tsr; @@ -150,7 +150,7 @@ static void rt_macb_isr(int irq) } -static void macb_mdio_write(struct rt_macb_eth *macb, rt_uint8_t reg, rt_uint16_t value) +static int macb_mdio_write(struct rt_macb_eth *macb, rt_uint8_t reg, rt_uint16_t value) { unsigned long netctl; unsigned long netstat; @@ -179,7 +179,7 @@ static void macb_mdio_write(struct rt_macb_eth *macb, rt_uint8_t reg, rt_uint16_ rt_sem_release(&macb->mdio_bus_lock); } -static rt_uint16_t macb_mdio_read(struct rt_macb_eth *macb, rt_uint8_t reg) +static int macb_mdio_read(struct rt_macb_eth *macb, rt_uint8_t reg) { unsigned long netctl; unsigned long netstat; @@ -298,12 +298,21 @@ void macb_update_link(void *param) { struct rt_macb_eth *macb = (struct rt_macb_eth *)param; rt_device_t dev = &macb->parent.parent; - rt_uint32_t status, status_change = 0; + int status, status_change = 0; rt_uint32_t link; rt_uint32_t media; rt_uint16_t adv, lpa; + /* Do a fake read */ status = macb_mdio_read(macb, MII_BMSR); + if (status < 0) + return; + + /* Read link and autonegotiation status */ + status = macb_mdio_read(macb, MII_BMSR); + if (status < 0) + return; + if ((status & BMSR_LSTATUS) == 0) link = 0; else @@ -403,7 +412,8 @@ static rt_err_t rt_macb_init(rt_device_t dev) | MACB_BIT(HRESP))); /* instal interrupt */ - rt_hw_interrupt_install(AT91SAM9260_ID_EMAC, rt_macb_isr, RT_NULL); + rt_hw_interrupt_install(AT91SAM9260_ID_EMAC, rt_macb_isr, + (void *)macb, "emac"); rt_hw_interrupt_umask(AT91SAM9260_ID_EMAC); rt_timer_init(&macb->timer, "link_timer", diff --git a/include/rthw.h b/include/rthw.h index 204f822a69..817b9f40f2 100644 --- a/include/rthw.h +++ b/include/rthw.h @@ -41,9 +41,10 @@ rt_uint8_t *rt_hw_stack_init(void *entry, void rt_hw_interrupt_init(void); void rt_hw_interrupt_mask(int vector); void rt_hw_interrupt_umask(int vector); -void rt_hw_interrupt_install(int vector, - rt_isr_handler_t new_handler, - rt_isr_handler_t *old_handler); +rt_isr_handler_t rt_hw_interrupt_install(int vector, + rt_isr_handler_t handler, + void *param, + char *name); void rt_hw_interrupt_handle(int vector); rt_base_t rt_hw_interrupt_disable(void); diff --git a/include/rtthread.h b/include/rtthread.h index 0048366fed..dbe48b492e 100644 --- a/include/rtthread.h +++ b/include/rtthread.h @@ -425,7 +425,15 @@ void rt_module_unload_sethook(void (*hook)(rt_module_t module)); /* * interrupt service */ -typedef void (*rt_isr_handler_t)(int vector); +typedef void (*rt_isr_handler_t)(int vector, void *param); + +struct rt_irq_desc { + char irq_name[RT_NAME_MAX]; + rt_isr_handler_t isr_handle; + void *param; + rt_uint32_t interrupt_cnt; +}; + /* * rt_interrupt_enter and rt_interrupt_leave only can be called by BSP diff --git a/libcpu/arm/at91sam926x/interrupt.c b/libcpu/arm/at91sam926x/interrupt.c index 31e49283dd..012ecc66aa 100755 --- a/libcpu/arm/at91sam926x/interrupt.c +++ b/libcpu/arm/at91sam926x/interrupt.c @@ -20,7 +20,8 @@ extern rt_uint32_t rt_interrupt_nest; /* exception and interrupt handler table */ -rt_isr_handler_t isr_table[MAX_HANDLERS]; +struct rt_irq_desc irq_desc[MAX_HANDLERS]; + rt_uint32_t rt_interrupt_from_thread, rt_interrupt_to_thread; rt_uint32_t rt_thread_switch_interrupt_flag; @@ -79,15 +80,16 @@ static rt_uint32_t at91sam9260_default_irq_priority[MAX_HANDLERS] = { void rt_hw_interrupt_mask(int irq); void rt_hw_interrupt_umask(int irq); -rt_isr_handler_t rt_hw_interrupt_handle(rt_uint32_t vector) +rt_isr_handler_t rt_hw_interrupt_handle(rt_uint32_t vector, void *param) { rt_kprintf("Unhandled interrupt %d occured!!!\n", vector); return RT_NULL; } -rt_isr_handler_t at91_gpio_irq_handle(rt_uint32_t vector) +rt_isr_handler_t at91_gpio_irq_handle(rt_uint32_t vector, void *param) { rt_uint32_t isr, pio, irq_n; + void *parameter; if (vector == AT91SAM9260_ID_PIOA) { @@ -111,7 +113,8 @@ rt_isr_handler_t at91_gpio_irq_handle(rt_uint32_t vector) { if (isr & 1) { - isr_table[irq_n](irq_n); + parameter = irq_desc[irq_n].param; + irq_desc[irq_n].isr_handle(irq_n, parameter); } isr >>= 1; irq_n++; @@ -160,13 +163,22 @@ void at91_aic_init(rt_uint32_t *priority) static void at91_gpio_irq_init() { + int i, idx; + char *name[] = {"PIOA", "PIOB", "PIOC"}; + at91_sys_write(AT91_PIOA+PIO_IDR, 0xffffffff); at91_sys_write(AT91_PIOB+PIO_IDR, 0xffffffff); at91_sys_write(AT91_PIOC+PIO_IDR, 0xffffffff); - isr_table[AT91SAM9260_ID_PIOA] = (rt_isr_handler_t)at91_gpio_irq_handle; - isr_table[AT91SAM9260_ID_PIOB] = (rt_isr_handler_t)at91_gpio_irq_handle; - isr_table[AT91SAM9260_ID_PIOC] = (rt_isr_handler_t)at91_gpio_irq_handle; + idx = AT91SAM9260_ID_PIOA; + for (i = 0; i < 3; i++) + { + rt_snprintf(irq_desc[idx].irq_name, RT_NAME_MAX - 1, name[i]); + irq_desc[idx].isr_handle = (rt_isr_handler_t)at91_gpio_irq_handle; + irq_desc[idx].param = RT_NULL; + irq_desc[idx].interrupt_cnt = 0; + idx++; + } rt_hw_interrupt_umask(AT91SAM9260_ID_PIOA); rt_hw_interrupt_umask(AT91SAM9260_ID_PIOB); @@ -192,7 +204,10 @@ void rt_hw_interrupt_init(void) /* init exceptions table */ for(idx=0; idx < MAX_HANDLERS; idx++) { - isr_table[idx] = (rt_isr_handler_t)rt_hw_interrupt_handle; + rt_snprintf(irq_desc[idx].irq_name, RT_NAME_MAX - 1, "default"); + irq_desc[idx].isr_handle = (rt_isr_handler_t)rt_hw_interrupt_handle; + irq_desc[idx].param = RT_NULL; + irq_desc[idx].interrupt_cnt = 0; } at91_gpio_irq_init(); @@ -289,16 +304,29 @@ void rt_hw_interrupt_umask(int irq) /** * This function will install a interrupt service routine to a interrupt. * @param vector the interrupt number - * @param new_handler the interrupt service routine to be installed - * @param old_handler the old interrupt service routine + * @param handler the interrupt service routine to be installed + * @param param the interrupt service function parameter + * @param name the interrupt name + * @return old handler */ -void rt_hw_interrupt_install(int vector, rt_isr_handler_t new_handler, rt_isr_handler_t *old_handler) +rt_isr_handler_t rt_hw_interrupt_install(int vector, rt_isr_handler_t handler, + void *param, char *name) { + rt_isr_handler_t old_handler = RT_NULL; + if(vector < MAX_HANDLERS) { - if (old_handler != RT_NULL) *old_handler = isr_table[vector]; - if (new_handler != RT_NULL) isr_table[vector] = new_handler; + old_handler = irq_desc[vector].isr_handle; + if (handler != RT_NULL) + { + rt_snprintf(irq_desc[vector].irq_name, RT_NAME_MAX - 1, "%s", name); + irq_desc[vector].isr_handle = (rt_isr_handler_t)handler; + irq_desc[vector].param = param; + irq_desc[vector].interrupt_cnt = 0; + } } + + return old_handler; } /*@}*/ @@ -335,3 +363,25 @@ static int at91_aic_set_type(unsigned irq, unsigned type) at91_sys_write(AT91_AIC_SMR(irq), smr | srctype); return 0; } + +#ifdef RT_USING_FINSH +void list_irq(void) +{ + int irq; + + rt_kprintf("number\tcount\tname\n"); + for (irq = 0; irq < MAX_HANDLERS; irq++) + { + if (rt_strncmp(irq_desc[irq].irq_name, "default", sizeof("default"))) + { + rt_kprintf("%02ld: %10ld %s\n", irq, irq_desc[irq].interrupt_cnt, irq_desc[irq].irq_name); + } + } +} + +#include +FINSH_FUNCTION_EXPORT(list_irq, list system irq); + +#endif + + diff --git a/libcpu/arm/at91sam926x/trap.c b/libcpu/arm/at91sam926x/trap.c index 2d09c2d56e..841c8b6813 100755 --- a/libcpu/arm/at91sam926x/trap.c +++ b/libcpu/arm/at91sam926x/trap.c @@ -138,12 +138,13 @@ void rt_hw_trap_resv(struct rt_hw_register *regs) rt_hw_cpu_shutdown(); } -extern rt_isr_handler_t isr_table[]; +extern struct rt_irq_desc irq_desc[]; void rt_hw_trap_irq() { rt_isr_handler_t isr_func; rt_uint32_t irqstat, irq, mask; + void *param; //rt_kprintf("irq interrupt request\n"); /* get irq number */ irq = at91_sys_read(AT91_AIC_IVR); @@ -158,11 +159,13 @@ void rt_hw_trap_irq() //at91_sys_write(AT91_AIC_EOICR, 0x55555555); /* get interrupt service routine */ - isr_func = isr_table[irq]; + isr_func = irq_desc[irq].isr_handle; + param = irq_desc[irq].param; /* turn to interrupt service routine */ - isr_func(irq); + isr_func(irq, param); at91_sys_write(AT91_AIC_EOICR, 0x55555555); //EIOCR must be write any value after interrupt, or else can't response next interrupt + irq_desc[irq].interrupt_cnt++; } void rt_hw_trap_fiq()