Commit 4ca5fe4e37ff264a11d83331df1efd552887fe22
authorMichel Pollet <buserror@gmail.com>
Tue, 22 Feb 2011 23:20:36 +0000 (23:20 +0000)
committerMichel Pollet <buserror@gmail.com>
Tue, 22 Feb 2011 23:20:36 +0000 (23:20 +0000)
Nothing to be shown for this work so far, the cool stuff hopefully
will come later...

Signed-off-by: Michel Pollet <buserror@gmail.com>
11 files changed:
simavr/sim/avr_adc.c
simavr/sim/avr_adc.h
simavr/sim/avr_extint.c
simavr/sim/avr_extint.h
simavr/sim/avr_ioport.c
simavr/sim/avr_spi.c
simavr/sim/avr_timer.c
simavr/sim/avr_uart.c
simavr/sim/sim_io.c
simavr/sim/sim_io.h
simavr/sim/sim_irq.c

index 3e010c95dbff4f8b04774458cac9d70b143620b1..f2b2606690f85ee99237bf5339f985712d31efc5 100644 (file)
@@ -212,9 +212,24 @@ static void avr_adc_reset(avr_io_t * port)
                avr_irq_register_notify(p->io.irq + i, avr_adc_irq_notify, p);
 }
 
+static const char * irq_names[ADC_IRQ_COUNT] = {
+       [ADC_IRQ_ADC0] = "16<adc0",
+       [ADC_IRQ_ADC1] = "16<adc1",
+       [ADC_IRQ_ADC2] = "16<adc2",
+       [ADC_IRQ_ADC3] = "16<adc3",
+       [ADC_IRQ_ADC4] = "16<adc4",
+       [ADC_IRQ_ADC5] = "16<adc5",
+       [ADC_IRQ_ADC6] = "16<adc6",
+       [ADC_IRQ_ADC7] = "16<adc7",
+       [ADC_IRQ_TEMP] = "16<temp",
+       [ADC_IRQ_IN_TRIGGER] = "<trigger_in",
+       [ADC_IRQ_OUT_TRIGGER] = ">trigger_out",
+};
+
 static avr_io_t        _io = {
        .kind = "adc",
        .reset = avr_adc_reset,
+       .irq_names = irq_names,
 };
 
 void avr_adc_init(avr_t * avr, avr_adc_t * p)
index cf4ac381594d183297901823d842c8f5f0795957..85f82cfec4479d42e3d7fe36b6802ecd65d7b74e 100644 (file)
@@ -48,7 +48,7 @@ enum {
 };
 
 // Get the internal IRQ corresponding to the INT
-#define AVR_IOCTL_ADC_GETIRQ AVR_IOCTL_DEF('a','d','c','i')
+#define AVR_IOCTL_ADC_GETIRQ AVR_IOCTL_DEF('a','d','c',' ')
 
 /*
  * Definition of a ADC mux mode.
index 5a900fca935dd54d613c985c8cee7b4e8a950671..12517394946485f0454497b29796784f7f59db0d 100644 (file)
@@ -69,9 +69,21 @@ static void avr_extint_reset(avr_io_t * port)
        }
 }
 
+static const char * irq_names[EXTINT_COUNT] = {
+       [EXTINT_IRQ_OUT_INT0] = "<int0",
+       [EXTINT_IRQ_OUT_INT1] = "<int1",
+       [EXTINT_IRQ_OUT_INT2] = "<int2",
+       [EXTINT_IRQ_OUT_INT3] = "<int3",
+       [EXTINT_IRQ_OUT_INT4] = "<int4",
+       [EXTINT_IRQ_OUT_INT5] = "<int5",
+       [EXTINT_IRQ_OUT_INT6] = "<int6",
+       [EXTINT_IRQ_OUT_INT7] = "<int7",
+};
+
 static avr_io_t        _io = {
        .kind = "extint",
        .reset = avr_extint_reset,
+       .irq_names = irq_names,
 };
 
 void avr_extint_init(avr_t * avr, avr_extint_t * p)
index c44e1e72c7eea2a3de10a8584c2e47152f587ad6..480e50550319191f802eda641670c0abdead732b 100644 (file)
@@ -36,7 +36,7 @@ enum {
 };
 
 // Get the internal IRQ corresponding to the INT
-#define AVR_IOCTL_EXTINT_GETIRQ() AVR_IOCTL_DEF('e','x','t','i')
+#define AVR_IOCTL_EXTINT_GETIRQ() AVR_IOCTL_DEF('i','n','t',' ')
 
 /*
  * This module is just a "relay" for the pin change IRQ in the IO port
index cb238eb1a5cd95e9978b15bdd53795b523a4e7b4..fd43454774b3d4b3916ddb87a92e7b62d88ab0c9 100644 (file)
@@ -159,10 +159,24 @@ static int avr_ioport_ioctl(struct avr_io_t * port, uint32_t ctl, void * io_para
        return res;
 }
 
+static const char * irq_names[IOPORT_IRQ_COUNT] = {
+       [IOPORT_IRQ_PIN0] = "=pin0",
+       [IOPORT_IRQ_PIN1] = "=pin1",
+       [IOPORT_IRQ_PIN2] = "=pin2",
+       [IOPORT_IRQ_PIN3] = "=pin3",
+       [IOPORT_IRQ_PIN4] = "=pin4",
+       [IOPORT_IRQ_PIN5] = "=pin5",
+       [IOPORT_IRQ_PIN6] = "=pin6",
+       [IOPORT_IRQ_PIN7] = "=pin7",
+       [IOPORT_IRQ_PIN_ALL] = "=all",
+       [IOPORT_IRQ_DIRECTION_ALL] = ">ddr",
+};
+
 static avr_io_t        _io = {
-       .kind = "io",
+       .kind = "port",
        .reset = avr_ioport_reset,
        .ioctl = avr_ioport_ioctl,
+       .irq_names = irq_names,
 };
 
 void avr_ioport_init(avr_t * avr, avr_ioport_t * p)
index 3b353285b60222f320937445078c0489addbbd06..05810bf2f32a9d07423ae192d022c730e15c1953 100644 (file)
@@ -82,9 +82,15 @@ void avr_spi_reset(struct avr_io_t *io)
        avr_irq_register_notify(p->io.irq + SPI_IRQ_INPUT, avr_spi_irq_input, p);
 }
 
+static const char * irq_names[SPI_IRQ_COUNT] = {
+       [SPI_IRQ_INPUT] = "8<in",
+       [SPI_IRQ_OUTPUT] = "8<out",
+};
+
 static avr_io_t        _io = {
        .kind = "spi",
        .reset = avr_spi_reset,
+       .irq_names = irq_names,
 };
 
 void avr_spi_init(avr_t * avr, avr_spi_t * p)
index b01b76f04aad28f5c0c937e3fdfad85409f59661..fdcb8e10c17760f4ee1407c84875f252b43bb31a 100644 (file)
@@ -399,9 +399,18 @@ static void avr_timer_reset(avr_io_t * port)
 
 }
 
+static const char * irq_names[TIMER_IRQ_COUNT] = {
+       [TIMER_IRQ_OUT_PWM0] = "8>pwm0",
+       [TIMER_IRQ_OUT_PWM1] = "8>pwm1",
+       [TIMER_IRQ_OUT_COMP + 0] = ">compa",
+       [TIMER_IRQ_OUT_COMP + 1] = ">compb",
+       [TIMER_IRQ_OUT_COMP + 2] = ">compc",
+};
+
 static avr_io_t        _io = {
        .kind = "timer",
        .reset = avr_timer_reset,
+       .irq_names = irq_names,
 };
 
 void avr_timer_init(avr_t * avr, avr_timer_t * p)
index 14f7bdbcbbf651259aa4921463fbd2150fe11888..b01ebe1fb098ee9b26a6f5691b456f6d890899e5 100644 (file)
@@ -222,10 +222,18 @@ static int avr_uart_ioctl(struct avr_io_t * port, uint32_t ctl, void * io_param)
        return res;
 }
 
+static const char * irq_names[UART_IRQ_COUNT] = {
+       [UART_IRQ_INPUT] = "8<in",
+       [UART_IRQ_OUTPUT] = "8>out",
+       [UART_IRQ_OUT_XON] = ">xon",
+       [UART_IRQ_OUT_XOFF] = ">xoff",
+};
+
 static avr_io_t        _io = {
        .kind = "uart",
        .reset = avr_uart_reset,
        .ioctl = avr_uart_ioctl,
+       .irq_names = irq_names,
 };
 
 void avr_uart_init(avr_t * avr, avr_uart_t * p)
index b23aad422458fcfabc02cd309f61d84c5f0d6718..f3df7a5f797be761020209181bff5b6d1afb7c62 100644 (file)
@@ -23,6 +23,7 @@
 #include <stdlib.h>
 #include <stdio.h>
 #include <string.h>
+#include <ctype.h>
 #include "sim_io.h"
 
 int
@@ -160,7 +161,7 @@ avr_iomem_getirq(
 {
        avr_io_addr_t a = AVR_DATA_TO_IO(addr);
        if (avr->io[a].irq == NULL) {
-               avr->io[a].irq = avr_alloc_irq(&avr->irq_pool, 0, 9, NULL /* TODO: names*/);
+               avr->io[a].irq = avr_alloc_irq(&avr->irq_pool, 0, 9, NULL);
                // mark the pin ones as filtered, so they only are raised when changing
                for (int i = 0; i < 8; i++)
                        avr->io[a].irq[i].flags |= IRQ_FLAG_FILTERED;
@@ -173,13 +174,60 @@ avr_io_setirqs(
                avr_io_t * io,
                uint32_t ctl,
                int count,
-               avr_irq_t * irqs)
+               avr_irq_t * irqs )
 {
        // allocate this module's IRQ
        io->irq_count = count;
-       io->irq = irqs ? irqs :
-               avr_alloc_irq(&io->avr->irq_pool, 0,
-                               count, NULL /* TODO: names*/);
+
+       if (!irqs) {
+               const char ** irq_names = NULL;
+
+               if (io->irq_names) {
+                       irq_names = malloc(count * sizeof(char*));
+                       memset(irq_names, 0, count * sizeof(char*));
+                       char buf[64];
+                       for (int i = 0; i < count; i++) {
+                               /*
+                                * this bit takes the io module 'kind' ("port")
+                                * the IRQ name ("=0") and the last character of the ioctl ('p','o','r','A')
+                                * to create a full name "=porta.0"
+                                */
+                               char * dst = buf;
+                               // copy the 'flags' of the name out
+                               const char * kind = io->irq_names[i];
+                               while (!isalpha(*kind))
+                                       *dst++ = *kind++;
+                               // add avr name
+//                             strcpy(dst, io->avr->mmcu);
+                               strcpy(dst, "avr");
+                               dst += strlen(dst);
+                               *dst ++ = '.';
+                               // add module 'kind'
+                               strcpy(dst, io->kind);
+                               dst += strlen(dst);
+                               // add port name, if any
+                               if ((ctl & 0xff) > ' ')
+                                       *dst ++ = tolower(ctl & 0xff);
+                               *dst ++ = '.';
+                               // add the rest of the irq name
+                               strcpy(dst, kind);
+                               dst += strlen(dst);
+                               *dst = 0;
+
+//                             printf("%s\n", buf);
+                               irq_names[i] = strdup(buf);
+                       }
+               }
+               irqs = avr_alloc_irq(&io->avr->irq_pool, 0,
+                                               count, irq_names);
+               if (irq_names) {
+                       for (int i = 0; i < count; i++)
+                               free((char*)irq_names[i]);
+                       free((char*)irq_names);
+               }
+       }
+
+       io->irq = irqs;
        io->irq_ioctl_get = ctl;
        return io->irq;
 }
index aa29a297995b0537740cddc8b8954c283daf0821..c3f01e5d0a757a0ef886f93f6c933421548ac2b9 100644 (file)
@@ -44,6 +44,8 @@ typedef struct avr_io_t {
        avr_t *                         avr;            // avr we are attached to
        const char *            kind;           // pretty name, for debug
 
+       const char ** irq_names;                // IRQ names
+
        uint32_t                        irq_ioctl_get;  // used to get irqs from this module
        int                                     irq_count;      // number of (optional) irqs
        struct avr_irq_t *      irq;            // optional external IRQs
@@ -74,7 +76,7 @@ avr_io_setirqs(
                avr_io_t * io,
                uint32_t ctl,
                int count,
-               avr_irq_t * irqs);
+               avr_irq_t * irqs );
 
 // register a callback for when IO register "addr" is read
 void
index 6e6954095acdbd5875967d2ca3aa6fbcff1688a4..634ea9c34d2b9f8d400f626437533ff183853488 100644 (file)
@@ -34,6 +34,31 @@ typedef struct avr_irq_hook_t {
        void * param;                           // "notify" parameter
 } avr_irq_hook_t;
 
+static void
+_avr_irq_pool_add(
+               avr_irq_pool_t * pool,
+               avr_irq_t * irq)
+{
+       if ((pool->count & 0xf) == 0) {
+               pool->irq = (avr_irq_t**)realloc(pool->irq,
+                               (pool->count + 16) * sizeof(avr_irq_t *));
+       }
+       pool->irq[pool->count++] = irq;
+       irq->pool = pool;
+}
+
+static void
+_avr_irq_pool_remove(
+               avr_irq_pool_t * pool,
+               avr_irq_t * irq)
+{
+       for (int i = 0; i < pool->count; i++)
+               if (pool->irq[i] == irq) {
+                       pool->irq[i] = 0;
+                       return;
+               }
+}
+
 void
 avr_init_irq(
                avr_irq_pool_t * pool,
@@ -46,6 +71,10 @@ avr_init_irq(
 
        for (int i = 0; i < count; i++) {
                irq[i].irq = base + i;
+               if (pool)
+                       _avr_irq_pool_add(pool, &irq[i]);
+               if (names && names[i])
+                       irq[i].name = strdup(names[i]);
        }
 }
 
@@ -82,14 +111,20 @@ avr_free_irq(
        if (!irq || !count)
                return;
        for (int i = 0; i < count; i++) {
+               avr_irq_t * iq = irq + i;
+               if (iq->pool)
+                       _avr_irq_pool_remove(iq->pool, iq);
+               if (iq->name)
+                       free((char*)iq->name);
+               iq->name = NULL;
                // purge hooks
-               avr_irq_hook_t *hook = irq->hook;
+               avr_irq_hook_t *hook = iq->hook;
                while (hook) {
                        avr_irq_hook_t * next = hook->next;
                        free(hook);
                        hook = next;
                }
-               irq->hook = NULL;
+               iq->hook = NULL;
        }
        // if that irq list was allocated by us, free it
        if (irq->flags & IRQ_FLAG_ALLOC)