Very big commit for a big rewrite of the pins configuration process, making it easier...
authorNathael Pajani <nathael.pajani@ed3l.fr>
Thu, 17 Apr 2014 21:56:33 +0000 (23:56 +0200)
committerNathael Pajani <nathael.pajani@ed3l.fr>
Tue, 8 Nov 2022 16:03:04 +0000 (17:03 +0100)
16 files changed:
core/pio.c [new file with mode: 0644]
core/system.c
drivers/adc.c
drivers/eeprom.c
drivers/gpio.c
drivers/i2c.c
drivers/serial.c
drivers/ssp.c
drivers/status_led.c [new file with mode: 0644]
drivers/timers.c
include/core/lpc_regs_12xx.h
include/core/pio.h [new file with mode: 0644]
include/drivers/gpio.h
include/drivers/ssp.h
include/drivers/status_led.h [new file with mode: 0644]
include/drivers/timers.h

diff --git a/core/pio.c b/core/pio.c
new file mode 100644 (file)
index 0000000..b2afd9f
--- /dev/null
@@ -0,0 +1,141 @@
+/****************************************************************************
+ *  core/pio.c
+ *
+ * Copyright 2012 Nathael Pajani <nathael.pajani@ed3l.fr>
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ *
+ *************************************************************************** */
+
+/***************************************************************************** */
+/*                GPIOs                                                        */
+/***************************************************************************** */
+
+
+
+#include <stdint.h>
+#include "core/lpc_regs_12xx.h"
+#include "core/lpc_core_cm0.h"
+#include "core/system.h"
+#include "core/pio.h"
+
+
+/***************************************************************************** */
+/*   Public access to GPIO setup   */
+static volatile uint32_t* pio_regs_handles_port0[PORT0_NB_PINS] = {
+       &(LPC_IO_CONTROL->pio0_0),
+       &(LPC_IO_CONTROL->pio0_1),
+       &(LPC_IO_CONTROL->pio0_2),
+       &(LPC_IO_CONTROL->pio0_3),
+       &(LPC_IO_CONTROL->pio0_4),
+       &(LPC_IO_CONTROL->pio0_5),
+       &(LPC_IO_CONTROL->pio0_6),
+       &(LPC_IO_CONTROL->pio0_7),
+       &(LPC_IO_CONTROL->pio0_8),
+       &(LPC_IO_CONTROL->pio0_9),
+       &(LPC_IO_CONTROL->pio0_10),
+       &(LPC_IO_CONTROL->pio0_11),
+       &(LPC_IO_CONTROL->pio0_12),
+       &(LPC_IO_CONTROL->pio0_13),
+       &(LPC_IO_CONTROL->pio0_14),
+       &(LPC_IO_CONTROL->pio0_15),
+       &(LPC_IO_CONTROL->pio0_16),
+       &(LPC_IO_CONTROL->pio0_17),
+       &(LPC_IO_CONTROL->pio0_18),
+       &(LPC_IO_CONTROL->pio0_19),
+       &(LPC_IO_CONTROL->pio0_20),
+       &(LPC_IO_CONTROL->pio0_21),
+       &(LPC_IO_CONTROL->pio0_22),
+       &(LPC_IO_CONTROL->pio0_23),
+       &(LPC_IO_CONTROL->pio0_24),
+       &(LPC_IO_CONTROL->pio0_25),
+       &(LPC_IO_CONTROL->pio0_26),
+       &(LPC_IO_CONTROL->pio0_27),
+       &(LPC_IO_CONTROL->pio0_28),
+       &(LPC_IO_CONTROL->pio0_29),
+       &(LPC_IO_CONTROL->pio0_30),
+       &(LPC_IO_CONTROL->pio0_31),
+};
+static volatile uint32_t* pio_regs_handles_port1[PORT1_NB_PINS] = {
+       &(LPC_IO_CONTROL->pio1_0),
+       &(LPC_IO_CONTROL->pio1_1),
+       &(LPC_IO_CONTROL->pio1_2),
+       &(LPC_IO_CONTROL->pio1_3),
+       &(LPC_IO_CONTROL->pio1_4),
+       &(LPC_IO_CONTROL->pio1_5),
+       &(LPC_IO_CONTROL->pio1_6),
+};
+static volatile uint32_t* pio_regs_handles_port2[PORT2_NB_PINS] = {
+       &(LPC_IO_CONTROL->pio2_0),
+       &(LPC_IO_CONTROL->pio2_1),
+       &(LPC_IO_CONTROL->pio2_2),
+       &(LPC_IO_CONTROL->pio2_3),
+       &(LPC_IO_CONTROL->pio2_4),
+       &(LPC_IO_CONTROL->pio2_5),
+       &(LPC_IO_CONTROL->pio2_6),
+       &(LPC_IO_CONTROL->pio2_7),
+       &(LPC_IO_CONTROL->pio2_8),
+       &(LPC_IO_CONTROL->pio2_9),
+       &(LPC_IO_CONTROL->pio2_10),
+       &(LPC_IO_CONTROL->pio2_11),
+       &(LPC_IO_CONTROL->pio2_12),
+       &(LPC_IO_CONTROL->pio2_13),
+       &(LPC_IO_CONTROL->pio2_14),
+       &(LPC_IO_CONTROL->pio2_15),
+};
+
+void pio_copy(struct pio* dst, struct pio* src)
+{
+       dst->port = src->port;
+       dst->pin = src->pin;
+       dst->alt_setting = src->alt_setting;
+}
+
+void config_pio(struct pio* pp, uint32_t mode)
+{
+       volatile uint32_t* handle = NULL;
+
+       switch (pp->port) {
+               case 0:
+                       if (pp->pin >= PORT0_NB_PINS)
+                               return;
+                       handle = pio_regs_handles_port0[pp->pin];
+                       break;
+               case 1:
+                       if (pp->pin >= PORT1_NB_PINS)
+                               return;
+                       handle = pio_regs_handles_port1[pp->pin];
+                       break;
+               case 2:
+                       if (pp->pin >= PORT2_NB_PINS)
+                               return;
+                       handle = pio_regs_handles_port2[pp->pin];
+                       break;
+               default:
+                       return;
+       }
+       /* Make sure IO_Config is clocked */
+       io_config_clk_on();
+
+       *handle = (LPC_IO_FUNC_ALT(pp->alt_setting) | mode);
+
+       /* Config done, power off IO_CONFIG block */
+       io_config_clk_off();
+}
+
+
+/* FIXME: We should add some system-wide way to "reserve" a pin, but anyway this
+ * would not prevent anyone from configuring the same pin for two diferent functions
+ * when not using our code.
+ */
index 3db2330..d2c2872 100644 (file)
@@ -277,35 +277,6 @@ void clkout_off(void)
 {
 }
 
-/***************************************************************************** */
-/*                    Peripheral Pins                                          */
-/***************************************************************************** */
-void Dummy_Pin_Config(void) {
-       do { } while (0);
-}
-
-void set_i2c_pins(void) __attribute__ ((weak, alias ("Dummy_Pin_Config")));
-void set_ssp_pins(void) __attribute__ ((weak, alias ("Dummy_Pin_Config")));
-void set_uarts_pins(void) __attribute__ ((weak, alias ("Dummy_Pin_Config")));
-void set_gpio_pins(void) __attribute__ ((weak, alias ("Dummy_Pin_Config")));
-void set_adc_pins(void) __attribute__ ((weak, alias ("Dummy_Pin_Config")));
-
-void system_set_default_pins(void)
-{
-       /* Set all pins as GPIO first, those used for something else will
-          override the settings in corresponding pin setup functions. */
-       set_gpio_pins();
-       set_uarts_pins();
-       set_i2c_pins();
-       set_ssp_pins();
-       set_adc_pins();
-}
-
-/* FIXME: We should add some system-wide way to "reserve" a pin.
-     This would not prevent anyone from configuring the same pin for two diferent
-     functions.
- */
-
 
 /***************************************************************************** */
 /* Note that if the systick core functions are used these will be overridden */
index d40ea21..3cffe61 100644 (file)
@@ -28,7 +28,7 @@
 #include "core/lpc_regs_12xx.h"
 #include "core/lpc_core_cm0.h"
 #include "core/system.h"
-#include "drivers/gpio.h"
+#include "core/pio.h"
 
 /* Should be as near to 9MHz as possible */
 #define adc_clk_Val  9000000
@@ -124,15 +124,15 @@ void adc_set_resolution(int bits)
 
 /***************************************************************************** */
 /*   ADC Setup : private part : Clocks, Pins, Power and Mode   */
+extern struct pio adc_pins[];
+
 void set_adc_pins(void)
 {
+       int i = 0;
        /* Configure ADC pins */
-       config_gpio(0, 30, (LPC_IO_FUNC_ALT(3) | LPC_IO_ANALOG));
-       config_gpio(0, 31, (LPC_IO_FUNC_ALT(3) | LPC_IO_ANALOG));
-       config_gpio(1, 0, (LPC_IO_FUNC_ALT(2) | LPC_IO_ANALOG));
-       config_gpio(1, 1, (LPC_IO_FUNC_ALT(2) | LPC_IO_ANALOG));
-       config_gpio(1, 2, (LPC_IO_FUNC_ALT(2) | LPC_IO_ANALOG));
-       config_gpio(1, 3, (LPC_IO_FUNC_ALT(1) | LPC_IO_ANALOG));
+       for (i = 0; adc_pins[i].port != 0xFF; i++) {
+               config_pio(&adc_pins[i], LPC_IO_ANALOG);
+       }
 }
 
 void adc_clk_update(void)
index a46b2e8..f6d786b 100644 (file)
@@ -25,9 +25,9 @@
 #include "core/lpc_regs_12xx.h"
 #include "core/lpc_core_cm0.h"
 #include "core/system.h"
+#include "core/pio.h"
 #include "lib/string.h"
 #include "drivers/i2c.h"
-#include "drivers/gpio.h"
 
 
 /***************************************************************************** */
 /* These are place-holders to set the SPI chip select low if the SPI driver is not used.
  * These dummy functions will be over-ridden by SPI ones if the SPI driver is used.
  */
-#define I2C_CS_PIN 15
+#define I2C_CS_GPIO   LPC_GPIO_0_15
 int I2C_CS_Default_Set(void)
 {
     struct lpc_gpio* gpio0 = LPC_GPIO_0;
-    config_gpio(0, I2C_CS_PIN, (LPC_IO_FUNC_ALT(0) | LPC_IO_MODE_PULL_UP | LPC_IO_DIGITAL));
+       struct pio i2c_eeprom_cs = I2C_CS_GPIO;
+    config_pio(&i2c_eeprom_cs, (LPC_IO_MODE_PULL_UP | LPC_IO_DIGITAL));
     /* Configure SPI_CS as output and set it low. */
-    gpio0->data_dir |= (1 << I2C_CS_PIN);
-    gpio0->clear = (1 << I2C_CS_PIN);
+    gpio0->data_dir |= (1 << i2c_eeprom_cs.pin);
+    gpio0->clear = (1 << i2c_eeprom_cs.pin);
        return 0;
 }
 void I2C_CS_Default_Release(void)
 {
        struct lpc_gpio* gpio0 = LPC_GPIO_0;
-    gpio0->set = (1 << I2C_CS_PIN);
+       struct pio i2c_eeprom_cs = I2C_CS_GPIO;
+    gpio0->set = (1 << i2c_eeprom_cs.pin);
 }
 
 int spi_device_cs_pull_low(void) __attribute__ ((weak, alias ("I2C_CS_Default_Set")));
index 308b32f..cde7f0d 100644 (file)
 
 
 /***************************************************************************** */
-/*   Public access to GPIO setup   */
-#define PORT0_NB_PINS 32
-#define PORT1_NB_PINS 7
-#define PORT2_NB_PINS 16
-static volatile uint32_t* gpio_regs_handles_port0[PORT0_NB_PINS] = {
-       &(LPC_IO_CONTROL->pio0_0),
-       &(LPC_IO_CONTROL->pio0_1),
-       &(LPC_IO_CONTROL->pio0_2),
-       &(LPC_IO_CONTROL->pio0_3),
-       &(LPC_IO_CONTROL->pio0_4),
-       &(LPC_IO_CONTROL->pio0_5),
-       &(LPC_IO_CONTROL->pio0_6),
-       &(LPC_IO_CONTROL->pio0_7),
-       &(LPC_IO_CONTROL->pio0_8),
-       &(LPC_IO_CONTROL->pio0_9),
-       &(LPC_IO_CONTROL->pio0_10),
-       &(LPC_IO_CONTROL->pio0_11),
-       &(LPC_IO_CONTROL->pio0_12),
-       &(LPC_IO_CONTROL->pio0_13),
-       &(LPC_IO_CONTROL->pio0_14),
-       &(LPC_IO_CONTROL->pio0_15),
-       &(LPC_IO_CONTROL->pio0_16),
-       &(LPC_IO_CONTROL->pio0_17),
-       &(LPC_IO_CONTROL->pio0_18),
-       &(LPC_IO_CONTROL->pio0_19),
-       &(LPC_IO_CONTROL->pio0_20),
-       &(LPC_IO_CONTROL->pio0_21),
-       &(LPC_IO_CONTROL->pio0_22),
-       &(LPC_IO_CONTROL->pio0_23),
-       &(LPC_IO_CONTROL->pio0_24),
-       &(LPC_IO_CONTROL->pio0_25),
-       &(LPC_IO_CONTROL->pio0_26),
-       &(LPC_IO_CONTROL->pio0_27),
-       &(LPC_IO_CONTROL->pio0_28),
-       &(LPC_IO_CONTROL->pio0_29),
-       &(LPC_IO_CONTROL->pio0_30),
-       &(LPC_IO_CONTROL->pio0_31),
-};
-static volatile uint32_t* gpio_regs_handles_port1[PORT1_NB_PINS] = {
-       &(LPC_IO_CONTROL->pio1_0),
-       &(LPC_IO_CONTROL->pio1_1),
-       &(LPC_IO_CONTROL->pio1_2),
-       &(LPC_IO_CONTROL->pio1_3),
-       &(LPC_IO_CONTROL->pio1_4),
-       &(LPC_IO_CONTROL->pio1_5),
-       &(LPC_IO_CONTROL->pio1_6),
-};
-static volatile uint32_t* gpio_regs_handles_port2[PORT2_NB_PINS] = {
-       &(LPC_IO_CONTROL->pio2_0),
-       &(LPC_IO_CONTROL->pio2_1),
-       &(LPC_IO_CONTROL->pio2_2),
-       &(LPC_IO_CONTROL->pio2_3),
-       &(LPC_IO_CONTROL->pio2_4),
-       &(LPC_IO_CONTROL->pio2_5),
-       &(LPC_IO_CONTROL->pio2_6),
-       &(LPC_IO_CONTROL->pio2_7),
-       &(LPC_IO_CONTROL->pio2_8),
-       &(LPC_IO_CONTROL->pio2_9),
-       &(LPC_IO_CONTROL->pio2_10),
-       &(LPC_IO_CONTROL->pio2_11),
-       &(LPC_IO_CONTROL->pio2_12),
-       &(LPC_IO_CONTROL->pio2_13),
-       &(LPC_IO_CONTROL->pio2_14),
-       &(LPC_IO_CONTROL->pio2_15),
-};
+/*   GPIO setup   */
 
-void config_gpio(uint8_t port, uint8_t pin, uint32_t mode)
-{
-       volatile uint32_t* handle = NULL;
 
-       switch (port) {
-               case 0:
-                       if (pin >= PORT0_NB_PINS)
-                               return;
-                       handle = gpio_regs_handles_port0[pin];
-                       break;
-               case 1:
-                       if (pin >= PORT1_NB_PINS)
-                               return;
-                       handle = gpio_regs_handles_port1[pin];
-                       break;
-               case 2:
-                       if (pin >= PORT2_NB_PINS)
-                               return;
-                       handle = gpio_regs_handles_port2[pin];
-                       break;
-               default:
-                       return;
+/* Set all GPIO used in a default state */
+extern struct pio gpio_pins[];
+
+void set_gpio_pins(void)
+{
+       int i = 0;
+       /* Set GPIO pins as GPIO */
+       for (i = 0; gpio_pins[i].port != 0xFF; i++) {
+               config_pio(&gpio_pins[i], LPC_IO_MODE_PULL_UP);
        }
-       /* Make sure IO_Config is clocked */
-       io_config_clk_on();
-       *handle = mode;
-       /* Config done, power off IO_CONFIG block */
-       io_config_clk_off();
 }
 
 void gpio_on(void)
@@ -133,7 +52,7 @@ void gpio_on(void)
        /* Provide power to GPIO control blocks */
        subsystem_power(LPC_SYS_ABH_CLK_CTRL_GPIO0, 1);
        subsystem_power(LPC_SYS_ABH_CLK_CTRL_GPIO1, 1);
-       /* FIXME : Power this one two if you use LQFP64 or LQFP100 packages */
+       /* FIXME : Power this one too if you use LQFP64 or LQFP100 packages */
        /* subsystem_power(LPC_SYS_ABH_CLK_CTRL_GPIO2, 1); */
 }
 void gpio_off(void)
@@ -145,118 +64,38 @@ void gpio_off(void)
 }
 
 
-/* Set all GPIO used on the GPIO_Demo module in a default state */
-void set_gpio_pins(void)
-{
-       struct lpc_io_control* ioctrl = LPC_IO_CONTROL;
-
-       /* Make sure IO_Config is clocked */
-       io_config_clk_on();
-
-       /* Configure GPIO pins */
-       ioctrl->pio0_0 = LPC_IO_FUNC_ALT(0) | LPC_IO_MODE_PULL_UP;
-       ioctrl->pio0_3 = LPC_IO_FUNC_ALT(0) | LPC_IO_MODE_PULL_UP;
-       ioctrl->pio0_4 = LPC_IO_FUNC_ALT(0) | LPC_IO_MODE_PULL_UP;
-       ioctrl->pio0_5 = LPC_IO_FUNC_ALT(0) | LPC_IO_MODE_PULL_UP;
-       ioctrl->pio0_6 = LPC_IO_FUNC_ALT(0) | LPC_IO_MODE_PULL_UP;
-       ioctrl->pio0_19 = LPC_IO_FUNC_ALT(0) | LPC_IO_MODE_PULL_UP;
-       ioctrl->pio0_20 = LPC_IO_FUNC_ALT(0) | LPC_IO_MODE_PULL_UP;
-       ioctrl->pio0_21 = LPC_IO_FUNC_ALT(0) | LPC_IO_MODE_PULL_UP;
-       ioctrl->pio0_22 = LPC_IO_FUNC_ALT(0) | LPC_IO_MODE_PULL_UP;
-       ioctrl->pio0_23 = LPC_IO_FUNC_ALT(0) | LPC_IO_MODE_PULL_UP;
-       ioctrl->pio0_24 = LPC_IO_FUNC_ALT(0) | LPC_IO_MODE_PULL_UP;
-       ioctrl->pio0_25 = LPC_IO_FUNC_ALT(6) | LPC_IO_MODE_PULL_UP;
-       ioctrl->pio0_26 = LPC_IO_FUNC_ALT(6) | LPC_IO_MODE_PULL_UP;
-       ioctrl->pio0_27 = LPC_IO_FUNC_ALT(0) | LPC_IO_MODE_PULL_UP;
-       ioctrl->pio0_28 = LPC_IO_FUNC_ALT(0) | LPC_IO_MODE_PULL_UP;
-       ioctrl->pio0_29 = LPC_IO_FUNC_ALT(0) | LPC_IO_MODE_PULL_UP;
-       /* ADC pins configured in ADC driver. Kept for info, for those not using them as ADC */
-       ioctrl->pio0_30 = LPC_IO_FUNC_ALT(1) | LPC_IO_MODE_PULL_UP; /* AD0 */
-       ioctrl->pio0_31 = LPC_IO_FUNC_ALT(1) | LPC_IO_MODE_PULL_UP; /* AD1 */
-       ioctrl->pio1_0 = LPC_IO_FUNC_ALT(1) | LPC_IO_MODE_PULL_UP; /* AD2 */
-       ioctrl->pio1_1 = LPC_IO_FUNC_ALT(1) | LPC_IO_MODE_PULL_UP; /* AD3 */
-       ioctrl->pio1_2 = LPC_IO_FUNC_ALT(0) | LPC_IO_MODE_PULL_UP; /* AD4 */
-       ioctrl->pio1_3 = LPC_IO_FUNC_ALT(0) | LPC_IO_MODE_PULL_UP; /* AD5 */
-       /* Bicolor led */
-       ioctrl->pio1_4 = LPC_IO_FUNC_ALT(0) | LPC_IO_MODE_PULL_UP; /* Green LED */
-       ioctrl->pio1_5 = LPC_IO_FUNC_ALT(0) | LPC_IO_MODE_PULL_UP; /* Red LED */
-       /* SPI pins */
-       ioctrl->pio0_14 = LPC_IO_FUNC_ALT(0) | LPC_IO_MODE_PULL_UP; /* SPI Clock */
-       ioctrl->pio0_15 = LPC_IO_FUNC_ALT(0) | LPC_IO_MODE_PULL_UP; /* SPI Chip Select */
-       ioctrl->pio0_16 = LPC_IO_FUNC_ALT(0) | LPC_IO_MODE_PULL_UP; /* SPI MISO */
-       ioctrl->pio0_17 = LPC_IO_FUNC_ALT(0) | LPC_IO_MODE_PULL_UP; /* SPI MOSI */
-       /* UART pins */
-       ioctrl->pio0_1 = LPC_IO_FUNC_ALT(0) | LPC_IO_MODE_PULL_UP; /* UART0 RxD */
-       ioctrl->pio0_2 = LPC_IO_FUNC_ALT(0) | LPC_IO_MODE_PULL_UP; /* UART0 TxD */
-       ioctrl->pio0_8 = LPC_IO_FUNC_ALT(0) | LPC_IO_MODE_PULL_UP; /* UART1 RxD */
-       ioctrl->pio0_9 = LPC_IO_FUNC_ALT(0) | LPC_IO_MODE_PULL_UP; /* UART1 TxD */
-       /* I2C pins */
-       ioctrl->pio0_10 = LPC_IO_FUNC_ALT(0) | LPC_IO_MODE_PULL_UP; /* I2C SCL */
-       ioctrl->pio0_11 = LPC_IO_FUNC_ALT(0) | LPC_IO_MODE_PULL_UP; /* I2C SDA */
-
-       /* Config done, power off IO_CONFIG block */
-       io_config_clk_off();
-}
-
-
-/* Most pins have GPIO function on function 0, but a few have it on another function ...
- * Return the function number for the GPIO function.
- */
-uint8_t lpc_io_func_gpio(uint8_t port, uint8_t pin){
-       switch (port) {
-               case 1:
-                       switch (pin) {
-                               case 0:
-                               case 1:
-                                       return 1;
-                       }
-                       break;
-               case 0:
-                       switch (pin) {
-                               case 13:
-                               case 30:
-                               case 31:
-                                       return 1;
-                               case 25:
-                               case 26:
-                                       return 6;
-                       }
-                       break;
-       }
-       return 0;
-}
-
+/***************************************************************************** */
+/* GPIO Interrupts Callbacks */
 static void (*gpio_calbacks_port0[PORT0_NB_PINS]) (uint32_t);
 static void (*gpio_calbacks_port1[PORT1_NB_PINS]) (uint32_t);
 static void (*gpio_calbacks_port2[PORT2_NB_PINS]) (uint32_t);
 
-
-int set_gpio_callback(void (*callback) (uint32_t), uint8_t port, uint8_t pin, uint8_t sense)
+int set_gpio_callback(void (*callback) (uint32_t), struct pio* gpio, uint8_t sense)
 {
        struct lpc_gpio* gpio_port = NULL;
        uint32_t irq = 0;
 
        /* Register the callback */
        /* FIXME : we should check that there were none registered for the selected pin */
-       switch (port) {
+       switch (gpio->port) {
                case 0:
-                       if (pin >= PORT0_NB_PINS)
+                       if (gpio->pin >= PORT0_NB_PINS)
                                return -EINVAL;
-                       gpio_calbacks_port0[pin] = callback;
+                       gpio_calbacks_port0[gpio->pin] = callback;
                        gpio_port = LPC_GPIO_0;
                        irq = PIO_0_IRQ;
                        break;
                case 1:
-                       if (pin >= PORT1_NB_PINS)
+                       if (gpio->pin >= PORT1_NB_PINS)
                                return -EINVAL;
-                       gpio_calbacks_port1[pin] = callback;
+                       gpio_calbacks_port1[gpio->pin] = callback;
                        gpio_port = LPC_GPIO_1;
                        irq = PIO_1_IRQ;
                        break;
                case 2:
-                       if (pin >= PORT2_NB_PINS)
+                       if (gpio->pin >= PORT2_NB_PINS)
                                return -EINVAL;
-                       gpio_calbacks_port2[pin] = callback;
+                       gpio_calbacks_port2[gpio->pin] = callback;
                        gpio_port = LPC_GPIO_2;
                        irq = PIO_2_IRQ;
                        break;
@@ -265,65 +104,65 @@ int set_gpio_callback(void (*callback) (uint32_t), uint8_t port, uint8_t pin, ui
        }
 
        /* Configure the pin as interrupt source */
-       gpio_port->data_dir &= ~(1 << pin); /* Input */
-       config_gpio(port, pin, (lpc_io_func_gpio(port, pin) | LPC_IO_DIGITAL));
+       gpio_port->data_dir &= ~(1 << gpio->pin); /* Input */
+       config_pio(gpio, LPC_IO_DIGITAL);
        switch (sense) {
                case EDGES_BOTH:
-                       gpio_port->int_sense &= ~(1 << pin);
-                       gpio_port->int_both_edges |= (1 << pin);
+                       gpio_port->int_sense &= ~(1 << gpio->pin);
+                       gpio_port->int_both_edges |= (1 << gpio->pin);
                        break;
                case EDGE_RISING:
-                       gpio_port->int_sense &= ~(1 << pin);
-                       gpio_port->int_both_edges &= ~(1 << pin);
-                       gpio_port->int_event |= (1 << pin);
+                       gpio_port->int_sense &= ~(1 << gpio->pin);
+                       gpio_port->int_both_edges &= ~(1 << gpio->pin);
+                       gpio_port->int_event |= (1 << gpio->pin);
                        break;
                case EDGE_FALLING:
-                       gpio_port->int_sense &= ~(1 << pin);
-                       gpio_port->int_both_edges &= ~(1 << pin);
-                       gpio_port->int_event &= ~(1 << pin);
+                       gpio_port->int_sense &= ~(1 << gpio->pin);
+                       gpio_port->int_both_edges &= ~(1 << gpio->pin);
+                       gpio_port->int_event &= ~(1 << gpio->pin);
                        break;
                case LEVEL_LOW:
-                       gpio_port->int_sense |= (1 << pin);
-                       gpio_port->int_both_edges &= ~(1 << pin);
-                       gpio_port->int_event &= ~(1 << pin);
+                       gpio_port->int_sense |= (1 << gpio->pin);
+                       gpio_port->int_both_edges &= ~(1 << gpio->pin);
+                       gpio_port->int_event &= ~(1 << gpio->pin);
                        break;
                case LEVEL_HIGH:
-                       gpio_port->int_sense |= (1 << pin);
-                       gpio_port->int_both_edges &= ~(1 << pin);
-                       gpio_port->int_event |= (1 << pin);
+                       gpio_port->int_sense |= (1 << gpio->pin);
+                       gpio_port->int_both_edges &= ~(1 << gpio->pin);
+                       gpio_port->int_event |= (1 << gpio->pin);
                        break;
                default: /* Not handled, do not activate the interrupt */
                        return -EINVAL;
        }
-       gpio_port->int_enable |= (1 << pin);
+       gpio_port->int_enable |= (1 << gpio->pin);
        NVIC_EnableIRQ(irq);
        return 0;
 }
-void remove_gpio_callback(uint8_t port, uint8_t pin)
+void remove_gpio_callback(struct pio* gpio)
 {
        struct lpc_gpio* gpio_port = NULL;
        uint32_t irq = 0;
 
        /* Remove the handler */
-       switch (port) {
+       switch (gpio->port) {
                case 0:
-                       if (pin >= PORT0_NB_PINS)
+                       if (gpio->pin >= PORT0_NB_PINS)
                                return;
-                       gpio_calbacks_port0[pin] = NULL;
+                       gpio_calbacks_port0[gpio->pin] = NULL;
                        gpio_port = LPC_GPIO_0;
                        irq = PIO_0_IRQ;
                        break;
                case 1:
-                       if (pin >= PORT1_NB_PINS)
+                       if (gpio->pin >= PORT1_NB_PINS)
                                return;
-                       gpio_calbacks_port1[pin] = NULL;
+                       gpio_calbacks_port1[gpio->pin] = NULL;
                        gpio_port = LPC_GPIO_1;
                        irq = PIO_1_IRQ;
                        break;
                case 2:
-                       if (pin >= PORT2_NB_PINS)
+                       if (gpio->pin >= PORT2_NB_PINS)
                                return;
-                       gpio_calbacks_port2[pin] = NULL;
+                       gpio_calbacks_port2[gpio->pin] = NULL;
                        gpio_port = LPC_GPIO_2;
                        irq = PIO_2_IRQ;
                        break;
@@ -331,7 +170,7 @@ void remove_gpio_callback(uint8_t port, uint8_t pin)
                        return;
        }
        /* And disable the interrupt */
-       gpio_port->int_enable &= ~(1 << pin);
+       gpio_port->int_enable &= ~(1 << gpio->pin);
        if (gpio_port->int_enable == 0) {
                NVIC_DisableIRQ(irq);
        }
@@ -343,7 +182,6 @@ void remove_gpio_callback(uint8_t port, uint8_t pin)
  * with the people doing the electronic design.
  * Use them if you place the signals generating interrupts on low numbered pins
  */
-#include "drivers/serial.h"
 void PIO_0_Handler(void)
 {
        struct lpc_gpio* gpio0 = LPC_GPIO_0;
@@ -406,93 +244,3 @@ void PIO_2_Handler(void)
 }
 
 
-/***************************************************************************** */
-/* Status LED */
-
-#define LED_RED 5
-#define LED_GREEN 4
-
-/* The status LED is on GPIO Port 1, pin 4 (PIO1_4) and Port 1, pin 5 (PIO1_5) */
-void status_led_config(void)
-{
-       struct lpc_gpio* gpio1 = LPC_GPIO_1;
-       uint32_t mode = (LPC_IO_MODE_PULL_UP | LPC_IO_DIGITAL | LPC_IO_DRIVE_HIGHCURENT);
-       /* Status Led GPIO */
-       config_gpio(1, LED_GREEN, (lpc_io_func_gpio(1, LED_GREEN) | mode));
-       config_gpio(1, LED_RED, (lpc_io_func_gpio(1, LED_RED) | mode));
-       /* Configure both as output */
-       gpio1->data_dir |= (1 << LED_GREEN) | (1 << LED_RED);
-       /* Turn both LEDs on */
-       //gpio1->set = (1 << LED_GREEN) | (1 << LED_RED);
-       gpio1->set = (1 << LED_GREEN);
-}
-
-void status_led(uint32_t val)
-{
-       struct lpc_gpio* gpio1 = LPC_GPIO_1;
-
-       switch (val) {
-               case red_only:
-                       gpio1->set = (1 << LED_RED);
-                       gpio1->clear = (1 << LED_GREEN);
-                       break;
-               case red_on:
-                       gpio1->set = (1 << LED_RED);
-                       break;
-               case red_off:
-                       gpio1->clear = (1 << LED_RED);
-                       break;
-               case red_toggle:
-                       gpio1->invert = (1 << LED_RED);
-                       break;
-               case green_only:
-                       gpio1->set = (1 << LED_GREEN);
-                       gpio1->clear = (1 << LED_RED);
-                       break;
-               case green_on:
-                       gpio1->set = (1 << LED_GREEN);
-                       break;
-               case green_off:
-                       gpio1->clear = (1 << LED_GREEN);
-                       break;
-               case green_toggle:
-                       gpio1->invert = (1 << LED_GREEN);
-                       break;
-               case both:
-                       gpio1->set = (1 << LED_GREEN) | (1 << LED_RED);
-                       break;
-               case toggle:
-                       gpio1->invert = (1 << LED_GREEN) | (1 << LED_RED);
-                       break;
-               case none:
-               default:
-                       gpio1->clear = (1 << LED_GREEN) | (1 << LED_RED);
-                       break;
-       }
-}
-
-void chenillard(uint32_t ms)
-{
-    status_led(red_only);
-    msleep(ms);
-    status_led(green_only);
-    msleep(ms);
-    status_led(none);
-    msleep(ms);
-    status_led(both);
-    msleep(ms);
-    status_led(none);
-    msleep(ms);
-    status_led(red_only);
-    msleep(ms);
-    status_led(red_only);
-    msleep(ms);
-    status_led(none);
-    msleep(ms);
-    status_led(green_only);
-    msleep(ms);
-    status_led(green_only);
-    msleep(ms);
-    status_led(none);
-    msleep(ms);
-}
index 3b47b27..26b99c4 100644 (file)
@@ -448,10 +448,15 @@ static void i2c_clock_on(uint32_t i2c_clk_freq)
        i2c->clk_duty_low = (scl_clk - i2c->clk_duty_high);
 }
 
+extern struct pio i2c0_pins[];
+
 void set_i2c_pins(void)
 {
-       config_gpio(0, 10, (LPC_IO_FUNC_ALT(2) | LPC_IO_OPEN_DRAIN_ENABLE)); /* True open drain */
-       config_gpio(0, 11, (LPC_IO_FUNC_ALT(2) | LPC_IO_OPEN_DRAIN_ENABLE));
+       int i = 0;
+       /* Configure I2C pins */
+       for (i = 0; i2c0_pins[i].port != 0xFF; i++) {
+               config_pio(&i2c0_pins[i], (LPC_IO_ANALOG | LPC_IO_OPEN_DRAIN_ENABLE));
+       }
 }
 
 void i2c_on(uint32_t i2c_clk_freq)
index 91ec299..f667cc3 100644 (file)
@@ -228,17 +228,22 @@ static uint32_t uart_mode_setup(uint32_t uart_num)
 /* Note : We MUST set LPC_IO_DIGITAL for Rx even if the bit is marked as "Reserved" in
  *        the datasheet !
  */
+extern struct pio uart0_pins[];
+extern struct pio uart1_pins[];
+
 static void uart_set_pin_func(uint32_t uart_num)
 {
-       /* Configure UART pins (Only Rx and Tx) */
+       int i = 0;
        switch (uart_num) {
                case 0:
-                       config_gpio(0, 1, (LPC_IO_FUNC_ALT(2) | LPC_IO_DIGITAL));
-                       config_gpio(0, 2, (LPC_IO_FUNC_ALT(2) | LPC_IO_DIGITAL));
+                       for (i = 0; uart0_pins[i].port != 0xFF; i++) {
+                               config_pio(&uart0_pins[i], LPC_IO_DIGITAL);
+                       }
                        break;
                case 1:
-                       config_gpio(0, 8, (LPC_IO_FUNC_ALT(2) | LPC_IO_DIGITAL));
-                       config_gpio(0, 9, (LPC_IO_FUNC_ALT(2) | LPC_IO_DIGITAL));
+                       for (i = 0; uart1_pins[i].port != 0xFF; i++) {
+                               config_pio(&uart1_pins[i], LPC_IO_DIGITAL);
+                       }
                        break;
        }
 }
index fdf15fa..601df27 100644 (file)
@@ -28,6 +28,7 @@
 #include "core/lpc_regs_12xx.h"
 #include "core/lpc_core_cm0.h"
 #include "core/system.h"
+#include "core/pio.h"
 #include "lib/string.h"
 #include "drivers/ssp.h"
 #include "drivers/gpio.h"
@@ -92,33 +93,34 @@ static uint32_t spi_cs_mutex = 0;
  * SPI bus.
  * Any data sent by the master on the SPI bus while the spi_cs_mutex is held will be lost.
  */
+#define SPI_CS_PIN  LPC_GPIO_0_15
 int spi_device_cs_pull_low(void)
 {
        struct lpc_gpio* gpio0 = LPC_GPIO_0;
+       struct pio spi_cs = SPI_CS_PIN;
 
        if (sync_lock_test_and_set(&spi_cs_mutex, 1) == 1) {
                return -EBUSY;
        }
 
        /* Configure pin as GPIO */
-       config_gpio(0, SPI_CS_PIN, (LPC_IO_FUNC_ALT(0) | LPC_IO_MODE_PULL_UP | LPC_IO_DIGITAL));
+       config_pio(&spi_cs, (LPC_IO_MODE_PULL_UP | LPC_IO_DIGITAL));
        /* Configure pin as output and set it low */
-       gpio0->data_dir |= (1 << SPI_CS_PIN);
-    gpio0->clear = (1 << SPI_CS_PIN);
+       gpio0->data_dir |= (1 << spi_cs.pin);
+    gpio0->clear = (1 << spi_cs.pin);
 
        return 0;
 }
 void spi_device_cs_release(void)
 {
        struct lpc_gpio* gpio0 = LPC_GPIO_0;
+       struct pio spi_cs = SPI_CS_PIN;
 
        /* Release mutex */
        sync_lock_release(&spi_cs_mutex);
 
        /* Set pin high */
-    gpio0->set = (1 << SPI_CS_PIN);
-       /* Configure pin as SPI again */
-       config_gpio(0, SPI_CS_PIN, (LPC_IO_FUNC_ALT(2) | LPC_IO_DIGITAL)); /* SPI Chip Select */
+    gpio0->set = (1 << spi_cs.pin);
 }
 
 
@@ -245,16 +247,18 @@ void ssp_clk_update(void)
        }
 }
 
-/* Configure main SPI pins, used in both master and device mode.
- * The slave select is not configured here as it's use is implementation dependant in master
- *  mode. In slave mode it is configured in the ssp_slave_on() function.
- */
-void set_ssp_pins(void)
+/* Configure all SPI pins. */
+extern struct pio ssp0_pins[];
+static void ssp_set_pin_func(uint32_t ssp_num)
 {
-       /* Main SPI pins */
-       config_gpio(0, 14, (LPC_IO_FUNC_ALT(2) | LPC_IO_DIGITAL)); /* SPI Clock */
-       config_gpio(0, 16, (LPC_IO_FUNC_ALT(2) | LPC_IO_DIGITAL)); /* SPI MISO */
-       config_gpio(0, 17, (LPC_IO_FUNC_ALT(2) | LPC_IO_DIGITAL)); /* SPI MOSI */
+       int i = 0;
+       switch (ssp_num) {
+               case 0:
+                       for (i = 0; ssp0_pins[i].port != 0xFF; i++) {
+                               config_pio(&ssp0_pins[i], LPC_IO_DIGITAL);
+                       }
+                       break;
+       }
 }
 
 
@@ -276,6 +280,10 @@ int ssp_master_on(uint8_t frame_type, uint8_t data_width, uint32_t rate )
        struct lpc_ssp* ssp = LPC_SSP0;
 
        NVIC_DisableIRQ(SSP0_IRQ);
+
+       /* Configure pins first */
+       ssp_set_pin_func(0); /* Only one SPI on the LPC1224 */
+
        /* Power up the ssp block */
        subsystem_power(LPC_SYS_ABH_CLK_CTRL_SSP0, 1);
 
@@ -316,9 +324,6 @@ int ssp_slave_on(uint8_t frame_type, uint8_t data_width, uint8_t out_en, uint32_
                ssp->ctrl_1 |= LPC_SSP_SLAVE_OUT_DISABLE;
        }
 
-       /* Use SPI as Device : configure the SSEL pin */
-       config_gpio(0, SPI_CS_PIN, (LPC_IO_FUNC_ALT(2) | LPC_IO_DIGITAL)); /* SPI Chip Select */
-
        /* Configure the clock : done after basic configuration.
         * Our clock must be at least 12 times the master clock */
        ssp_current_clk = ssp_clk_on(max_rate * 16);
@@ -326,6 +331,8 @@ int ssp_slave_on(uint8_t frame_type, uint8_t data_width, uint8_t out_en, uint32_
        /* Enable SSP */
        ssp->ctrl_1 |= LPC_SSP_ENABLE;
 
+       ssp_set_pin_func(0);
+
        NVIC_EnableIRQ(SSP0_IRQ);
        return 0; /* Config OK */
 }
diff --git a/drivers/status_led.c b/drivers/status_led.c
new file mode 100644 (file)
index 0000000..1c75327
--- /dev/null
@@ -0,0 +1,124 @@
+/****************************************************************************
+ *  drivers/status_led.c
+ *
+ * Copyright 2012 Nathael Pajani <nathael.pajani@ed3l.fr>
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ *
+*************************************************************************** */
+
+/***************************************************************************** */
+/*                Status Led                                                   */
+/***************************************************************************** */
+
+
+#include <stdint.h>
+#include "core/lpc_regs_12xx.h"
+#include "core/system.h"
+#include "core/pio.h"
+#include "drivers/status_led.h"
+
+
+/***************************************************************************** */
+/* Status LED is the bicolors red/green led on the GPIO Demo module */
+
+/* The status LED is on GPIO Port 1, pin 4 (PIO1_4) and Port 1, pin 5 (PIO1_5) */
+#define LED_RED    5
+#define LED_GREEN  4
+
+void status_led_config(void)
+{
+       struct lpc_gpio* gpio1 = LPC_GPIO_1;
+       uint32_t mode = (LPC_IO_MODE_PULL_UP | LPC_IO_DIGITAL | LPC_IO_DRIVE_HIGHCURENT);
+       struct pio red_led = LPC_GPIO_1_4;
+       struct pio green_led = LPC_GPIO_1_5;
+       /* Status Led GPIO */
+       config_pio(&green_led, mode);
+       config_pio(&red_led, mode);
+       /* Configure both as output */
+       gpio1->data_dir |= (1 << LED_GREEN) | (1 << LED_RED);
+       /* Turn both LEDs on */
+       //gpio1->set = (1 << LED_GREEN) | (1 << LED_RED);
+       gpio1->set = (1 << LED_GREEN);
+}
+
+void status_led(uint32_t val)
+{
+       struct lpc_gpio* gpio1 = LPC_GPIO_1;
+
+       switch (val) {
+               case red_only:
+                       gpio1->set = (1 << LED_RED);
+                       gpio1->clear = (1 << LED_GREEN);
+                       break;
+               case red_on:
+                       gpio1->set = (1 << LED_RED);
+                       break;
+               case red_off:
+                       gpio1->clear = (1 << LED_RED);
+                       break;
+               case red_toggle:
+                       gpio1->toggle = (1 << LED_RED);
+                       break;
+               case green_only:
+                       gpio1->set = (1 << LED_GREEN);
+                       gpio1->clear = (1 << LED_RED);
+                       break;
+               case green_on:
+                       gpio1->set = (1 << LED_GREEN);
+                       break;
+               case green_off:
+                       gpio1->clear = (1 << LED_GREEN);
+                       break;
+               case green_toggle:
+                       gpio1->toggle = (1 << LED_GREEN);
+                       break;
+               case both:
+                       gpio1->set = (1 << LED_GREEN) | (1 << LED_RED);
+                       break;
+               case toggle:
+                       gpio1->toggle = (1 << LED_GREEN) | (1 << LED_RED);
+                       break;
+               case none:
+               default:
+                       gpio1->clear = (1 << LED_GREEN) | (1 << LED_RED);
+                       break;
+       }
+}
+
+void chenillard(uint32_t ms)
+{
+    status_led(red_only);
+    msleep(ms);
+    status_led(green_only);
+    msleep(ms);
+    status_led(none);
+    msleep(ms);
+    status_led(both);
+    msleep(ms);
+    status_led(none);
+    msleep(ms);
+    status_led(red_only);
+    msleep(ms);
+    status_led(red_only);
+    msleep(ms);
+    status_led(none);
+    msleep(ms);
+    status_led(green_only);
+    msleep(ms);
+    status_led(green_only);
+    msleep(ms);
+    status_led(none);
+    msleep(ms);
+}
index 21e2ab6..0edd3e9 100644 (file)
@@ -198,18 +198,36 @@ int timer_setup(uint32_t timer_num, struct timer_config* conf)
 }
 
 
-/* Setup one pin to use as match or capture pin
- * This configure function can be used only for pins on port 0.
- * Use LPC_TIMER_*B*_CHANNEL_*_PIN_* definitions for the pin number and either
- *   LPC_TIMER_PIN_FUNC_CAPTURE or LPC_TIMER_PIN_FUNC_MATCH for the function.
- * Note: These pins are not setup using the usual system set default pins functions
- *   as most functions may be affected to many different pins, and the use of the
- *   timers does no require the use of pins.
- */
+/* Setup timer pins to be used as match or capture pin  */
+extern struct pio timer0_pins[];
+extern struct pio timer1_pins[];
+extern struct pio timer2_pins[];
+extern struct pio timer3_pins[];
+
 #define LPC_TIMER_PIN_CONFIG   (LPC_IO_MODE_PULL_UP | LPC_IO_DIGITAL | LPC_IO_DRIVE_HIGHCURENT)
-void timer_pins_setup(uint8_t port, uint8_t pin_num, uint32_t func)
+static void timer_pins_setup(uint32_t timer_num)
 {
-       config_gpio(port, pin_num, (func | LPC_TIMER_PIN_CONFIG));
+       int i = 0;
+       struct pio* timer_pins = NULL;
+       switch (timer_num) {
+               case LPC_TIMER_16B0:
+                       timer_pins = timer0_pins;
+                       break;
+               case LPC_TIMER_16B1:
+                       timer_pins = timer1_pins;
+                       break;
+               case LPC_TIMER_32B0:
+                       timer_pins = timer2_pins;
+                       break;
+               case LPC_TIMER_32B1:
+                       timer_pins = timer3_pins;
+                       break;
+               default:
+                       return;
+       }
+       for (i = 0; timer_pins[i].port != 0xFF; i++) {
+               config_pio(&timer_pins[i], LPC_TIMER_PIN_CONFIG);
+       }
 }
 
 /* Power up a timer.
@@ -241,6 +259,8 @@ void timer_on(uint32_t timer_num, uint32_t clkrate)
        }
        timer->regs->prescale = prescale;
 
+       timer_pins_setup(timer_num);
+
        NVIC_EnableIRQ(timer_devices[timer_num].irq);
 }
 
index 14cdcea..80dafb5 100644 (file)
@@ -444,7 +444,7 @@ struct lpc_gpio
        volatile uint32_t out;        /* 0x08 : Port output Register (R/W) */
        volatile uint32_t set;        /* 0x0C : Port output set Register (-/W) */
        volatile uint32_t clear;      /* 0x10 : Port output clear Register (-/W) */
-       volatile uint32_t invert;     /* 0x14 : Port output invert Register (-/W) */
+       volatile uint32_t toggle;     /* 0x14 : Port output invert Register (-/W) */
        uint32_t reserved_1[2];
        volatile uint32_t data_dir;   /* 0x20 : Data direction Register (R/W) */
        volatile uint32_t int_sense;  /* 0x24 : Interrupt sense Register (R/W) */
diff --git a/include/core/pio.h b/include/core/pio.h
new file mode 100644 (file)
index 0000000..84b4f90
--- /dev/null
@@ -0,0 +1,262 @@
+/****************************************************************************
+ *  core/pio.h
+ *
+ * Copyright 2014 Nathael Pajani <nathael.pajani@ed3l.fr>
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ *
+ ****************************************************************************/
+
+#ifndef CORE_PIO_H
+#define CORE_PIO_H
+
+#include <stdint.h>
+
+struct pio {
+    uint8_t port;  /* 0xFF indicates the end of a pin array */
+    uint8_t pin;
+    uint8_t alt_setting;
+};
+
+#define ARRAY_LAST_PIN   {0xFF, 0xFF, 0xFF}
+
+
+#define PORT0_NB_PINS 32
+#define PORT1_NB_PINS 7
+#define PORT2_NB_PINS 16
+
+void pio_copy(struct pio* dst, struct pio* src);
+
+void config_pio(struct pio* pp, uint32_t mode);
+
+
+/****************************************************************************/
+/*  GPIO Pins  */
+#define LPC_GPIO_0_0  {0,  0, 0}
+#define LPC_GPIO_0_1  {0,  1, 0}
+#define LPC_GPIO_0_2  {0,  2, 0}
+#define LPC_GPIO_0_3  {0,  3, 0}
+#define LPC_GPIO_0_4  {0,  4, 0}
+#define LPC_GPIO_0_5  {0,  5, 0}
+#define LPC_GPIO_0_6  {0,  6, 0}
+#define LPC_GPIO_0_7  {0,  7, 0}
+#define LPC_GPIO_0_8  {0,  8, 0}
+#define LPC_GPIO_0_9  {0,  9, 0}
+#define LPC_GPIO_0_10 {0, 10, 0}
+#define LPC_GPIO_0_11 {0, 11, 0}
+#define LPC_GPIO_0_12 {0, 12, 0}
+#define LPC_GPIO_0_13 {0, 13, 1}
+#define LPC_GPIO_0_14 {0, 14, 0}
+#define LPC_GPIO_0_15 {0, 15, 0}
+#define LPC_GPIO_0_16 {0, 16, 0}
+#define LPC_GPIO_0_17 {0, 17, 0}
+#define LPC_GPIO_0_18 {0, 18, 0}
+#define LPC_GPIO_0_19 {0, 19, 0}
+#define LPC_GPIO_0_20 {0, 20, 0}
+#define LPC_GPIO_0_21 {0, 21, 0}
+#define LPC_GPIO_0_22 {0, 22, 0}
+#define LPC_GPIO_0_23 {0, 23, 0}
+#define LPC_GPIO_0_24 {0, 24, 0}
+#define LPC_GPIO_0_25 {0, 25, 6}
+#define LPC_GPIO_0_26 {0, 26, 6}
+#define LPC_GPIO_0_27 {0, 27, 0}
+#define LPC_GPIO_0_28 {0, 28, 0}
+#define LPC_GPIO_0_29 {0, 29, 0}
+#define LPC_GPIO_0_30 {0, 30, 1}
+#define LPC_GPIO_0_31 {0, 31, 1}
+
+#define LPC_GPIO_1_0  {1,  0, 1}
+#define LPC_GPIO_1_1  {1,  1, 1}
+#define LPC_GPIO_1_2  {1,  2, 0}
+#define LPC_GPIO_1_3  {1,  3, 0}
+#define LPC_GPIO_1_4  {1,  4, 0}
+#define LPC_GPIO_1_5  {1,  5, 0}
+#define LPC_GPIO_1_6  {1,  6, 0}
+
+#define LPC_GPIO_2_0  {2,  0, 0}
+#define LPC_GPIO_2_1  {2,  1, 0}
+#define LPC_GPIO_2_2  {2,  2, 0}
+#define LPC_GPIO_2_3  {2,  3, 0}
+#define LPC_GPIO_2_4  {2,  4, 0}
+#define LPC_GPIO_2_5  {2,  5, 0}
+#define LPC_GPIO_2_6  {2,  6, 0}
+#define LPC_GPIO_2_7  {2,  7, 0}
+#define LPC_GPIO_2_8  {2,  8, 1}
+#define LPC_GPIO_2_9  {2,  9, 1}
+#define LPC_GPIO_2_10 {2, 10, 1}
+#define LPC_GPIO_2_11 {2, 11, 0}
+#define LPC_GPIO_2_12 {2, 12, 0}
+#define LPC_GPIO_2_13 {2, 13, 0}
+#define LPC_GPIO_2_14 {2, 14, 0}
+#define LPC_GPIO_2_15 {2, 15, 0}
+
+
+/****************************************************************************/
+/*  CLKOUT and Reset Pin  */
+#define LPC_CLKOUT_PIO_0_12 {0, 12, 2}
+#define LPC_RESET_PIO_0_13  {0, 13, 0}
+
+
+/****************************************************************************/
+/*  SWD (Debug) pins */
+#define LPC_SWD_SWCLK_PIO_0_18 {0, 18, 1}
+#define LPC_SWD_SWCLK_PIO_0_26 {0, 26, 0}
+#define LPC_SWD_SWDIO_PIO_0_25 {0, 25, 0}
+#define LPC_SWD_SWDIO_PIO_1_2  {1,  2, 1}
+
+
+/****************************************************************************/
+/*  UART0 Rx/Tx Pins  */
+#define LPC_UART0_RX_PIO_0_1  {0,  1, 2}
+#define LPC_UART0_RX_PIO_2_1  {2,  1, 4}
+#define LPC_UART0_TX_PIO_0_2  {0,  2, 2}
+#define LPC_UART0_TX_PIO_2_2  {2,  2, 4}
+/* UART0 - Other UART function pins */
+#define LPC_UART0_CTS_PIO_0_7 {0,  7, 2}
+#define LPC_UART0_CTS_PIO_2_4 {2,  4, 4}
+#define LPC_UART0_DCD_PIO_0_5 {0,  5, 2}
+#define LPC_UART0_DCD_PIO_2_6 {2,  6, 4}
+#define LPC_UART0_DSR_PIO_0_4 {0,  4, 2}
+#define LPC_UART0_DSR_PIO_2_7 {2,  7, 4}
+#define LPC_UART0_DTR_PIO_0_3 {0,  3, 2}
+#define LPC_UART0_DTR_PIO_2_3 {2,  3, 4}
+#define LPC_UART0_RI_PIO_0_6  {0,  6, 2}
+#define LPC_UART0_RI_PIO_2_5  {2,  5, 4}
+#define LPC_UART0_RTS_PIO_0_0 {0,  0, 2}
+#define LPC_UART0_RTS_PIO_2_0 {2,  0, 5}  /* FIXME: Doc does not list func 1 ... maybe its func 4 */
+
+/*  UART1 Rx/Tx Pins  */
+#define LPC_UART1_RX_PIO_0_8  {0,  8, 2}
+#define LPC_UART1_RX_PIO_2_11 {2, 11, 5}
+#define LPC_UART1_RX_PIO_2_12 {2, 12, 3}
+#define LPC_UART1_TX_PIO_0_9  {0,  9, 2}
+#define LPC_UART1_TX_PIO_2_10 {2, 10, 5}
+#define LPC_UART1_TX_PIO_2_13 {2, 13, 3}
+
+/****************************************************************************/
+/*  I2C Pins  */
+#define LPC_I2C0_SCL_PIO_0_10 {0, 10, 2}
+#define LPC_I2C0_SDA_PIO_0_11 {0, 11, 2}
+
+/****************************************************************************/
+/*  SPI Pins  */
+/* SSP 0 */
+#define LPC_SSP0_SCLK_PIO_0_14 {0, 14, 2}
+#define LPC_SSP0_MOSI_PIO_0_17 {0, 17, 2}
+#define LPC_SSP0_MISO_PIO_0_16 {0, 16, 2}
+#define LPC_SSP0_SSEL_PIO_0_15 {0, 15, 2}
+
+
+/****************************************************************************/
+/*  ADC Pins  */
+#define LPC_ADC_AD0_PIO_0_30  {0, 30, 3}
+#define LPC_ADC_AD1_PIO_0_31  {0, 31, 3}
+#define LPC_ADC_AD2_PIO_1_0   {1,  0, 2}
+#define LPC_ADC_AD3_PIO_1_1   {1,  1, 2}
+#define LPC_ADC_AD4_PIO_1_2   {1,  2, 2}
+#define LPC_ADC_AD5_PIO_1_3   {1,  4, 1}
+#define LPC_ADC_AD6_PIO_1_4   {1,  4, 1}
+#define LPC_ADC_AD7_PIO_1_5   {1,  5, 1}
+
+
+/****************************************************************************/
+/*  Timer Pins  */
+
+/* 16 bits timer 0 match pins */
+#define LPC_TIMER_16B0_M0_PIO_0_11 {0, 11, 4}
+#define LPC_TIMER_16B0_M0_PIO_0_28 {0, 28, 4}
+#define LPC_TIMER_16B0_M0_PIO_2_0  {2,  0, 4}
+#define LPC_TIMER_16B0_M1_PIO_0_12 {0, 12, 4}
+#define LPC_TIMER_16B0_M1_PIO_0_29 {0, 29, 4}
+#define LPC_TIMER_16B0_M1_PIO_2_1  {2,  1, 4}
+/* 16 bits timer 0 capture pins */
+#define LPC_TIMER_16B0_C0_PIO_0_11 {0, 11, 3}
+#define LPC_TIMER_16B0_C0_PIO_0_28 {0, 28, 3}
+#define LPC_TIMER_16B0_C0_PIO_2_0  {2,  0, 3}
+#define LPC_TIMER_16B0_C1_PIO_0_12 {0, 12, 3}
+#define LPC_TIMER_16B0_C1_PIO_0_29 {0, 29, 3}
+#define LPC_TIMER_16B0_C1_PIO_2_1  {2,  1, 3}
+
+/* 16 bits timer 1 match pins */
+#define LPC_TIMER_16B1_M0_PIO_0_15 {0, 15, 4}
+#define LPC_TIMER_16B1_M0_PIO_1_5  {1,  5, 3}
+#define LPC_TIMER_16B1_M0_PIO_2_2  {2,  2, 3}
+#define LPC_TIMER_16B1_M1_PIO_0_16 {0, 16, 4}
+#define LPC_TIMER_16B1_M1_PIO_1_6  {1,  6, 2}
+#define LPC_TIMER_16B1_M1_PIO_2_3  {2,  3, 3}
+/* 16 bits timer 1 capture pins */
+#define LPC_TIMER_16B1_C0_PIO_0_15 {0, 15, 3}
+#define LPC_TIMER_16B1_C0_PIO_1_5  {1,  5, 2}
+#define LPC_TIMER_16B1_C0_PIO_2_2  {2,  2, 2}
+#define LPC_TIMER_16B1_C1_PIO_0_16 {0, 16, 3}
+#define LPC_TIMER_16B1_C1_PIO_1_6  {1,  6, 1}
+#define LPC_TIMER_16B1_C1_PIO_2_3  {2,  3, 2}
+
+/* 32 bits timer 0 match pins */
+#define LPC_TIMER_32B0_M0_PIO_0_1  {0,  1, 4}
+#define LPC_TIMER_32B0_M0_PIO_0_18 {0, 18, 4}
+#define LPC_TIMER_32B0_M0_PIO_2_4  {2,  4, 3}
+#define LPC_TIMER_32B0_M1_PIO_0_2  {0,  2, 4}
+#define LPC_TIMER_32B0_M1_PIO_0_19 {0, 19, 4}
+#define LPC_TIMER_32B0_M1_PIO_2_5  {2,  5, 3}
+#define LPC_TIMER_32B0_M2_PIO_0_3  {0,  3, 4}
+#define LPC_TIMER_32B0_M2_PIO_0_20 {0, 20, 4}
+#define LPC_TIMER_32B0_M2_PIO_2_6  {2,  6, 3}
+#define LPC_TIMER_32B0_M3_PIO_0_4  {0,  4, 4}
+#define LPC_TIMER_32B0_M3_PIO_0_21 {0, 21, 4}
+#define LPC_TIMER_32B0_M3_PIO_2_7  {2,  7, 3}
+/* 32 bits timer 0 capture pins */
+#define LPC_TIMER_32B0_C0_PIO_0_1  {0,  1, 3}
+#define LPC_TIMER_32B0_C0_PIO_0_18 {0, 18, 3}
+#define LPC_TIMER_32B0_C0_PIO_2_4  {2,  4, 2}
+#define LPC_TIMER_32B0_C1_PIO_0_2  {0,  2, 3}
+#define LPC_TIMER_32B0_C1_PIO_0_19 {0, 19, 3}
+#define LPC_TIMER_32B0_C1_PIO_2_5  {2,  5, 2}
+#define LPC_TIMER_32B0_C2_PIO_0_3  {0,  3, 3}
+#define LPC_TIMER_32B0_C2_PIO_0_20 {0, 20, 3}
+#define LPC_TIMER_32B0_C2_PIO_2_6  {2,  6, 2}
+#define LPC_TIMER_32B0_C3_PIO_0_4  {0,  4, 3}
+#define LPC_TIMER_32B0_C3_PIO_0_21 {0, 21, 3}
+#define LPC_TIMER_32B0_C3_PIO_2_7  {2,  7, 2}
+
+/* 32 bits timer 1 match pins */
+#define LPC_TIMER_32B1_M0_PIO_0_6  {0,  6, 4}
+#define LPC_TIMER_32B1_M0_PIO_0_23 {0, 23, 4}
+#define LPC_TIMER_32B1_M0_PIO_2_8  {2,  8, 3}
+#define LPC_TIMER_32B1_M1_PIO_0_7  {0,  7, 4}
+#define LPC_TIMER_32B1_M1_PIO_0_24 {0, 24, 4}
+#define LPC_TIMER_32B1_M1_PIO_2_9  {2,  9, 3}
+#define LPC_TIMER_32B1_M2_PIO_0_8  {0,  8, 4}
+#define LPC_TIMER_32B1_M2_PIO_0_25 {0, 25, 4}
+#define LPC_TIMER_32B1_M2_PIO_2_10 {2, 10, 3}
+#define LPC_TIMER_32B1_M3_PIO_0_9  {0,  9, 4}
+#define LPC_TIMER_32B1_M3_PIO_0_26 {0, 26, 4}
+#define LPC_TIMER_32B1_M3_PIO_2_11 {2, 11, 3}
+/* 32 bits timer 1 capture pins */
+#define LPC_TIMER_32B1_C0_PIO_0_6  {0,  6, 3}
+#define LPC_TIMER_32B1_C0_PIO_0_23 {0, 23, 3}
+#define LPC_TIMER_32B1_C0_PIO_2_8  {2,  8, 2}
+#define LPC_TIMER_32B1_C1_PIO_0_7  {0,  7, 3}
+#define LPC_TIMER_32B1_C1_PIO_0_24 {0, 24, 3}
+#define LPC_TIMER_32B1_C1_PIO_2_9  {2,  9, 2}
+#define LPC_TIMER_32B1_C2_PIO_0_8  {0,  8, 3}
+#define LPC_TIMER_32B1_C2_PIO_0_25 {0, 25, 3}
+#define LPC_TIMER_32B1_C2_PIO_2_10 {2, 10, 2}
+#define LPC_TIMER_32B1_C3_PIO_0_9  {0,  9, 3}
+#define LPC_TIMER_32B1_C3_PIO_0_26 {0, 26, 3}
+#define LPC_TIMER_32B1_C3_PIO_2_11 {2, 11, 2}
+
+
+
+#endif /* CORE_PIO_H */
index 1017520..a0a3793 100644 (file)
 
 
 #include <stdint.h>
+#include "core/pio.h"
 
 
 /***************************************************************************** */
 /*   Public access to GPIO setup   */
 
 
-void config_gpio(uint8_t port, uint8_t pin, uint32_t mode);
-
 enum gpio_interrupt_senses {
        EDGES_BOTH = 0,
        EDGE_FALLING,
@@ -40,39 +39,11 @@ enum gpio_interrupt_senses {
 };
 
 
-/* Most pins have GPIO function on function 0, but a few have it on another function ...
- * Return the function number for the GPIO function.
- */
-uint8_t lpc_io_func_gpio(uint8_t port, uint8_t pin);
-
-int set_gpio_callback(void (*callback) (uint32_t), uint8_t port, uint8_t pin, uint8_t sense);
-void remove_gpio_callback(uint8_t port, uint8_t pin);
+int set_gpio_callback(void (*callback) (uint32_t), struct pio* gpio, uint8_t sense);
+void remove_gpio_callback(struct pio* gpio);
 
 void gpio_on(void);
 void gpio_off(void);
 
-/***************************************************************************** */
-/* Status LED */
-/* The status LED is on GPIO Port 1, pin 4 (PIO1_4) and Port 1, pin 5 (PIO1_5) */
-void status_led_config(void);
-
-void status_led(uint32_t val);
-
-void chenillard(uint32_t ms);
-
-enum led_status {
-       none = 0,
-       red_only,
-       red_on,
-       red_off,
-       red_toggle,
-       green_only,
-       green_on,
-       green_off,
-       green_toggle,
-       both,
-       toggle,
-};
-
 
 #endif /* DRIVERS_GPIO_H */
index 15a2e45..f78aaf7 100644 (file)
@@ -27,7 +27,6 @@
 /***************************************************************************** */
 
 #include <stdint.h>
-#include "drivers/gpio.h"
 
 
 /* Set this to 1 for use of this driver in a multitasking OS, it will activate the SPI Mutex */
@@ -38,7 +37,6 @@ enum spi_fifo_or_pooling {
        SPI_USE_FIFO = 1,
 };
 
-#define SPI_CS_PIN 15
 
 /***************************************************************************** */
 /* SPI device mode slave select sharing.
@@ -91,9 +89,6 @@ int spi_transfer_multiple_frames(uint16_t* data_out, int size, uint16_t* data_in
 /***************************************************************************** */
 uint32_t ssp_clk_on(uint32_t rate);
 void ssp_clk_update(void);
-void set_ssp_pins(void);
-
-
 
 /***************************************************************************** */
 /* SSP Setup as master */
diff --git a/include/drivers/status_led.h b/include/drivers/status_led.h
new file mode 100644 (file)
index 0000000..50ecc96
--- /dev/null
@@ -0,0 +1,52 @@
+/****************************************************************************
+ *  drivers/status_led.h
+ *
+ * Copyright 2012 Nathael Pajani <nathael.pajani@ed3l.fr>
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ *
+ *************************************************************************** */
+
+#ifndef DRIVERS_STATUS_LED_H
+#define DRIVERS_STATUS_LED_H
+
+
+#include <stdint.h>
+
+
+/***************************************************************************** */
+/* Status LED */
+/* The status LED is on GPIO Port 1, pin 4 (PIO1_4) and Port 1, pin 5 (PIO1_5) */
+void status_led_config(void);
+
+void status_led(uint32_t val);
+
+void chenillard(uint32_t ms);
+
+enum led_status {
+       none = 0,
+       red_only,
+       red_on,
+       red_off,
+       red_toggle,
+       green_only,
+       green_on,
+       green_off,
+       green_toggle,
+       both,
+       toggle,
+};
+
+
+#endif /* DRIVERS_STATUS_LED_H */
index a3dff99..316a5fe 100644 (file)
@@ -101,62 +101,6 @@ void timer_set_match(uint32_t timer_num, uint32_t channel, uint32_t val);
 int timer_setup(uint32_t timer_num, struct timer_config* conf);
 
 
-/* Some alternate pins for timers are on port 2, not handled by our code as they are
- *   unavailable on the 48 pins LQFP package used in the GPIO Demo module.
- * Some alternate pins for timers are on port 1, not handled by our code to get simpler code ...
- * Note that the alternate function numbers for most capture and match functions on
- *   port 2 are 2 and 3 instead of 3 and 4 !
- */
-/* 16 bits timer 0 match / capture pins */
-#define LPC_TIMER_16B0_CHANNEL_0_PIO_28  28
-#define LPC_TIMER_16B0_CHANNEL_1_PIO_29  29
-#define LPC_TIMER_16B0_CHANNEL_0_PIO_11  11
-#define LPC_TIMER_16B0_CHANNEL_1_PIO_12  12
-/* Alternate on PIO2_0 and PIO2_1 */
-
-/* 16 bits timer 1 match / capture pins */
-#define LPC_TIMER_16B1_CHANNEL_0_PIO_15  15
-#define LPC_TIMER_16B1_CHANNEL_1_PIO_16  16
-/* Alternate on PIO1_5 and PIO1_6 */
-/* Alternate on PIO2_2 and PIO2_3 */
-
-/* 32 bits timer 0 match / capture pins */
-#define LPC_TIMER_32B0_CHANNEL_0_PIO_1   1
-#define LPC_TIMER_32B0_CHANNEL_1_PIO_2   2
-#define LPC_TIMER_32B0_CHANNEL_2_PIO_3   3
-#define LPC_TIMER_32B0_CHANNEL_3_PIO_4   4
-#define LPC_TIMER_32B0_CHANNEL_0_PIO_18  18
-#define LPC_TIMER_32B0_CHANNEL_1_PIO_19  19
-#define LPC_TIMER_32B0_CHANNEL_2_PIO_20  20
-#define LPC_TIMER_32B0_CHANNEL_3_PIO_21  21
-/* Alternate on PIO2_4 to PIO2_7 */
-
-/* 32 bits timer 1 match / capture pins */
-#define LPC_TIMER_32B1_CHANNEL_0_PIO_6   6
-#define LPC_TIMER_32B1_CHANNEL_1_PIO_7   7
-#define LPC_TIMER_32B1_CHANNEL_2_PIO_8   8
-#define LPC_TIMER_32B1_CHANNEL_3_PIO_9   9
-#define LPC_TIMER_32B1_CHANNEL_0_PIO_23  23
-#define LPC_TIMER_32B1_CHANNEL_1_PIO_24  24
-#define LPC_TIMER_32B1_CHANNEL_2_PIO_25  25
-#define LPC_TIMER_32B1_CHANNEL_3_PIO_26  26
-/* Alternate on PIO2_8 to PIO2_11 */
-
-/* Capture or match alternate function select for port 0 pins */
-#define LPC_TIMER_PIN_FUNC_CAPTURE  LPC_IO_FUNC_ALT(3)
-#define LPC_TIMER_PIN_FUNC_MATCH    LPC_IO_FUNC_ALT(4)
-
-
-/* Setup one pin to use as match or capture pin
- * This configure function can be used only for pins on port 0.
- * Use LPC_TIMER_*B*_CHANNEL_*_PIO_* definitions for the pin number and either
- *   LPC_TIMER_PIN_FUNC_CAPTURE or LPC_TIMER_PIN_FUNC_MATCH for the function.
- * Note: These pins are not setup using the usual system set default pins functions
- *   as most functions may be affected to many different pins, and the use of the
- *   timers does no require the use of pins.
- */
-void timer_pins_setup(uint8_t port, uint8_t pin_num, uint32_t func);
-
 
 /* Power up a timer.
  * Note that clkrate should be a divider of the main clock frequency chosed