--- /dev/null
+/****************************************************************************
+ * 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.
+ */
{
}
-/***************************************************************************** */
-/* 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 */
#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
/***************************************************************************** */
/* 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)
#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")));
/***************************************************************************** */
-/* 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)
/* 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)
}
-/* 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;
}
/* 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;
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);
}
* 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;
}
-/***************************************************************************** */
-/* 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);
-}
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)
/* 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;
}
}
#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"
* 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);
}
}
}
-/* 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;
+ }
}
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);
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);
/* Enable SSP */
ssp->ctrl_1 |= LPC_SSP_ENABLE;
+ ssp_set_pin_func(0);
+
NVIC_EnableIRQ(SSP0_IRQ);
return 0; /* Config OK */
}
--- /dev/null
+/****************************************************************************
+ * 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);
+}
}
-/* 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.
}
timer->regs->prescale = prescale;
+ timer_pins_setup(timer_num);
+
NVIC_EnableIRQ(timer_devices[timer_num].irq);
}
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) */
--- /dev/null
+/****************************************************************************
+ * 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 */
#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,
};
-/* 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 */
/***************************************************************************** */
#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 */
SPI_USE_FIFO = 1,
};
-#define SPI_CS_PIN 15
/***************************************************************************** */
/* SPI device mode slave select sharing.
/***************************************************************************** */
uint32_t ssp_clk_on(uint32_t rate);
void ssp_clk_update(void);
-void set_ssp_pins(void);
-
-
/***************************************************************************** */
/* SSP Setup as master */
--- /dev/null
+/****************************************************************************
+ * 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 */
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