Move all base apps to a base subdirectory in apps. This prepares for merge of modules...
authorNathael Pajani <nathael.pajani@ed3l.fr>
Wed, 9 Sep 2015 20:10:01 +0000 (22:10 +0200)
committerNathael Pajani <nathael.pajani@ed3l.fr>
Tue, 8 Nov 2022 16:14:23 +0000 (17:14 +0100)
29 files changed:
adc/Makefile [new file with mode: 0644]
adc/README [new file with mode: 0644]
adc/main.c [new file with mode: 0644]
eeprom/Makefile [new file with mode: 0644]
eeprom/README [new file with mode: 0644]
eeprom/main.c [new file with mode: 0644]
epaper/Makefile [new file with mode: 0644]
epaper/README [new file with mode: 0644]
epaper/Techno-Innov_bw_epaper.epaper [new file with mode: 0644]
epaper/image_converter/.gitignore [new file with mode: 0644]
epaper/image_converter/Makefile [new file with mode: 0644]
epaper/image_converter/convert.c [new file with mode: 0644]
epaper/main.c [new file with mode: 0644]
epaper/tibug_bw_epaper.epaper [new file with mode: 0644]
gpio_intr/Makefile [new file with mode: 0644]
gpio_intr/README [new file with mode: 0644]
gpio_intr/main.c [new file with mode: 0644]
i2c_temp/Makefile [new file with mode: 0644]
i2c_temp/README [new file with mode: 0644]
i2c_temp/main.c [new file with mode: 0644]
lcd_char/Makefile [new file with mode: 0644]
lcd_char/README [new file with mode: 0644]
lcd_char/main.c [new file with mode: 0644]
ledstrip/Makefile [new file with mode: 0644]
ledstrip/README [new file with mode: 0644]
ledstrip/main.c [new file with mode: 0644]
ultrasonic_sensor/Makefile [new file with mode: 0644]
ultrasonic_sensor/README [new file with mode: 0644]
ultrasonic_sensor/main.c [new file with mode: 0644]

diff --git a/adc/Makefile b/adc/Makefile
new file mode 100644 (file)
index 0000000..91407f3
--- /dev/null
@@ -0,0 +1,10 @@
+# Makefile for GPIO Demo Module apps
+
+NAME = $(shell basename $(CURDIR))
+
+.PHONY: $(NAME).bin
+$(NAME).bin:
+       @make -C ../.. --no-print-directory NAME=$(NAME) apps/$(NAME)/$@
+
+clean mrproper:
+       @make -C ../.. --no-print-directory $@
diff --git a/adc/README b/adc/README
new file mode 100644 (file)
index 0000000..faf1d07
--- /dev/null
@@ -0,0 +1,36 @@
+ADC and TMP36 Example
+
+Copyright 2013 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/>.
+ *
+ *************************************************************************** */
+
+This example shows the support of the internal ADC, with conversion examples for
+a TMP36 analog temperature sensor and a CdS photoresistor.
+
+The conversion results are sent on the UART0 serial line (115200 8n1) at
+regular intervals, and the status led flashes the rest of the time.
+
+The output looks like this :
+ ADC(0): 684 (raw: 0x02ac)
+ TMP36: 29,36 (orig: 248, raw: 00f8)
+
+The first line displays the decimal and hexadecimal value of the raw
+conversion result, on which was the luminosity sensor.
+The second line displays the TMP36 temperature, which is not very acurate at
+ambient temperature, with the corresponding decimal and hexadecimal raw
+conversion values.
diff --git a/adc/main.c b/adc/main.c
new file mode 100644 (file)
index 0000000..7a8cec1
--- /dev/null
@@ -0,0 +1,180 @@
+/****************************************************************************
+ *   apps/adc/main.c
+ *
+ * ADC example
+ *
+ * Copyright 2013-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/>.
+ *
+ *************************************************************************** */
+
+
+#include <stdint.h>
+#include "core/lpc_regs_12xx.h"
+#include "core/lpc_core_cm0.h"
+#include "core/pio.h"
+#include "core/system.h"
+#include "core/systick.h"
+#include "lib/stdio.h"
+#include "drivers/serial.h"
+#include "drivers/gpio.h"
+#include "extdrv/status_led.h"
+#include "drivers/adc.h"
+
+
+#define MODULE_VERSION    0x04
+#define MODULE_NAME "GPIO Demo Module"
+
+
+#define SELECTED_FREQ  FREQ_SEL_48MHz
+
+/***************************************************************************** */
+/* Pins configuration */
+/* pins blocks are passed to set_pins() for pins configuration.
+ * Unused pin blocks can be removed safely with the corresponding set_pins() call
+ * All pins blocks may be safelly merged in a single block for single set_pins() call..
+ */
+const struct pio_config common_pins[] = {
+       /* UART 0 */
+       { LPC_UART0_RX_PIO_0_1,  LPC_IO_DIGITAL },
+       { LPC_UART0_TX_PIO_0_2,  LPC_IO_DIGITAL },
+       ARRAY_LAST_PIO,
+};
+
+const struct pio_config adc_pins[] = {
+       { LPC_ADC_AD0_PIO_0_30, LPC_IO_ANALOG },
+       { LPC_ADC_AD1_PIO_0_31, LPC_IO_ANALOG },
+       { LPC_ADC_AD2_PIO_1_0,  LPC_IO_ANALOG },
+       { LPC_ADC_AD3_PIO_1_1,  LPC_IO_ANALOG },
+       { LPC_ADC_AD4_PIO_1_2,  LPC_IO_ANALOG },
+       { LPC_ADC_AD5_PIO_1_3,  LPC_IO_ANALOG },
+       ARRAY_LAST_PIO,
+};
+
+const struct pio status_led_green = LPC_GPIO_1_4;
+const struct pio status_led_red = LPC_GPIO_1_5;
+
+/***************************************************************************** */
+/* This will display the integer value read on the ADC, between 0 and 1024.
+ * ADC must be initialised prior to calls to adc_display() (it means that adc_on()
+ *    must be called before using this function.
+ * adc_num is an ADC channel number (integer between 0 and 7)
+ *    use LPC_ADC_NUM(x) for channel selection.
+ * returns ADC convertion value or negative value on error.
+ */
+int adc_display(int adc_num, int uart_num)
+{
+       uint16_t val = 0;
+       int ret = 0;
+
+       adc_start_convertion_once(adc_num, 0);
+       msleep(10);
+       ret = adc_get_value(&val, adc_num);
+       if (ret < 0) {
+               return ret;
+       } else {
+               /* Always display, even if value has already been read */
+               char buff[40];
+               int len = 0;
+               len = snprintf(buff, 40, "ADC(%d): %d (raw: 0x%04x)\r\n", adc_num, val, val);
+               serial_write(uart_num, buff, len);
+       }
+       return val;
+}
+
+/* Display the temperature computed from adc convertion of the voltage output of
+ * a TMP36 analog temperature sensor
+ * ADC must be initialised prior to calls to TMP36_display() (it means that adc_on()
+ *    must be called before using this function.
+ * adc_num is an ADC channel number (integer between 0 and 7)
+ *    use LPC_ADC_NUM(x) for channel selection.
+ */
+void TMP36_display(int adc_num, int uart_num)
+{
+       uint16_t val = 0;
+       int ret = 0;
+
+       adc_start_convertion_once(adc_num, 0);
+       msleep(8);
+       ret = adc_get_value(&val, adc_num);
+       if (ret == 0) {
+               char buff[60];
+               int len = 0;
+               int micro_volts = 0;
+               /* depends on vref, should use a precise 3.0V Vref and multiply by 3000 */
+               micro_volts = (val * 3200);
+               int converted = ((micro_volts / 100) - 5000);
+               len = snprintf(buff, 60, "TMP36: %d,%d (orig: %d, raw: %04x)\r\n",
+                                               (converted / 100), (converted % 100), val, val);
+               serial_write(uart_num, buff, len);
+       }
+}
+
+
+/***************************************************************************** */
+void system_init()
+{
+       /* Stop the watchdog */
+       stop_watchdog(); /* Do it right now, before it gets a chance to break in */
+
+       /* Note: Brown-Out detection must be powered to operate the ADC. adc_on() will power
+        *  it back on if called after system_init() */
+       system_brown_out_detection_config(0);
+       system_set_default_power_state();
+       clock_config(SELECTED_FREQ);
+       set_pins(common_pins);
+       set_pins(adc_pins);
+       gpio_on();
+       status_led_config(&status_led_green, &status_led_red);
+       /* System tick timer MUST be configured and running in order to use the sleeping
+        * functions */
+       systick_timer_on(1); /* 1ms */
+       systick_start();
+}
+
+/* Define our fault handler. This one is not mandatory, the dummy fault handler
+ * will be used when it's not overridden here.
+ * Note : The default one does a simple infinite loop. If the watchdog is deactivated
+ * the system will hang.
+ */
+void fault_info(const char* name, uint32_t len)
+{
+       serial_write(0, name, len);
+       /* Wait for end of Tx */
+       serial_flush(0);
+       /* FIXME : Perform soft reset of the micro-controller ! */
+       while (1);
+}
+
+
+
+/***************************************************************************** */
+int main(void) {
+       system_init();
+       uart_on(0, 115200, NULL);
+       adc_on();
+
+       while (1) {
+               chenillard(500);
+               /* ADC Test */
+               adc_display(LPC_ADC_NUM(0), 0);
+               TMP36_display(LPC_ADC_NUM(1), 0);
+       }
+       return 0;
+}
+
+
+
diff --git a/eeprom/Makefile b/eeprom/Makefile
new file mode 100644 (file)
index 0000000..91407f3
--- /dev/null
@@ -0,0 +1,10 @@
+# Makefile for GPIO Demo Module apps
+
+NAME = $(shell basename $(CURDIR))
+
+.PHONY: $(NAME).bin
+$(NAME).bin:
+       @make -C ../.. --no-print-directory NAME=$(NAME) apps/$(NAME)/$@
+
+clean mrproper:
+       @make -C ../.. --no-print-directory $@
diff --git a/eeprom/README b/eeprom/README
new file mode 100644 (file)
index 0000000..e7460fe
--- /dev/null
@@ -0,0 +1,24 @@
+EEPROM support example
+
+Copyright 2013 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/>.
+ *
+ *************************************************************************** */
+
+This example shows the support of the onboard I2C eeprom memory
+
+TODO
diff --git a/eeprom/main.c b/eeprom/main.c
new file mode 100644 (file)
index 0000000..24eb6d8
--- /dev/null
@@ -0,0 +1,245 @@
+/****************************************************************************
+ *   apps/eeprom/main.c
+ *
+ *
+ *
+ * Copyright 2013-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/>.
+ *
+ *************************************************************************** */
+
+
+#include <stdint.h>
+#include "core/lpc_regs_12xx.h"
+#include "core/lpc_core_cm0.h"
+#include "core/pio.h"
+#include "core/system.h"
+#include "core/systick.h"
+#include "lib/stdio.h"
+#include "drivers/i2c.h"
+#include "extdrv/eeprom.h"
+#include "drivers/serial.h"
+#include "drivers/gpio.h"
+#include "extdrv/status_led.h"
+
+
+#ifndef MODULE_SERIAL_NUM
+#define MODULE_SERIAL_NUM 10
+#endif
+#define MODULE_VERSION    0x04
+#define MODULE_NAME "GPIO Demo Module"
+
+
+#define EEPROM_WRITE
+#undef EEPROM_WRITE
+
+#define SELECTED_FREQ  FREQ_SEL_48MHz
+
+/***************************************************************************** */
+/* Pins configuration */
+/* pins blocks are passed to set_pins() for pins configuration.
+ * Unused pin blocks can be removed safely with the corresponding set_pins() call
+ * All pins blocks may be safelly merged in a single block for single set_pins() call..
+ */
+const struct pio_config common_pins[] = {
+       /* UART 0 */
+       { LPC_UART0_RX_PIO_0_1,  LPC_IO_DIGITAL },
+       { LPC_UART0_TX_PIO_0_2,  LPC_IO_DIGITAL },
+       /* I2C 0 */
+       { LPC_I2C0_SCL_PIO_0_10, (LPC_IO_DIGITAL | LPC_IO_OPEN_DRAIN_ENABLE) },
+       { LPC_I2C0_SDA_PIO_0_11, (LPC_IO_DIGITAL | LPC_IO_OPEN_DRAIN_ENABLE) },
+       ARRAY_LAST_PIO,
+};
+
+const struct pio button_gpio = LPC_GPIO_0_12; /* ISP Used as button */
+const struct pio led_gpio = LPC_GPIO_0_4; /* Led toggle on ISP button press */
+
+const struct pio status_led_green = LPC_GPIO_1_4;
+const struct pio status_led_red = LPC_GPIO_1_5;
+
+const struct pio i2c_eeprom_cs = LPC_GPIO_0_15;
+
+
+/***************************************************************************** */
+/* EEPROM support */
+
+/* Module identification support for DTPlug and DomoTab */
+
+/* The eeprom on the GPIO Demo module must reply on address 0xA8 */
+#define EEPROM_ADDR  0xA8
+
+/* Module capabilities */
+#define UEXT_MOD_HAS_NONE  0
+#define UEXT_MOD_HAS_UART (1 << 0)
+#define UEXT_MOD_HAS_I2C  (1 << 1)
+#define UEXT_MOD_HAS_SPI  (1 << 2)
+
+struct module_desc {
+       uint16_t serial_number;
+       uint8_t version;
+       uint8_t header_size;
+       uint8_t capabilities; /* Bit mask of UEXT_MOD_HAS_* */
+       uint8_t name_offset;
+       uint8_t name_size;
+       uint8_t image_offset;
+       uint16_t image_size;
+} __attribute__ ((packed));
+
+
+
+/* EEPROM Chip select for the GPIO Demo module.
+ * Set the SPI SSEL pin low.
+ * These functions are specific to the mod_gpio_demo and domotab modules which
+ * have access to their onboard EEPROM.
+ * It is used to release the gate that blocks the SCL signal to the EEPROM,
+ *   allowing multiple eeproms with the same address to be accessed one at a time
+ *   on the same I2C Bus, which gives a way to both identify modules presence and
+ *   module function, name, and pther capabilities.
+ * When the SPI is used as slave, the master has the control of the SPI SSEL signal
+ *   and the EEPROM should not be accessed by the module.
+ * Other I2C EEPROMs should not need these functions.
+ */
+int mod_gpio_demo_eeprom_cs_pull_low(void)
+{
+       /* Configure SPI_CS as output and set it low. */
+       config_gpio(&i2c_eeprom_cs, 0, GPIO_DIR_OUT, 0);
+       return 0;
+}
+void mod_gpio_demo_eeprom_cs_release(void)
+{
+       struct lpc_gpio* gpio_port_regs = LPC_GPIO_REGS(i2c_eeprom_cs.port);
+       gpio_port_regs->set = (1 << i2c_eeprom_cs.pin);
+}
+
+
+/* Module description support */
+
+#define DUMP_BUFF_SIZE 80
+void module_desc_dump(uint8_t serial_num)
+{
+       char buff[DUMP_BUFF_SIZE];
+       int len = 0, ret = 0;
+       struct module_desc desc;
+
+       mod_gpio_demo_eeprom_cs_pull_low();
+       /* Read module descriptor structure from eeprom */
+       ret = eeprom_read(EEPROM_ADDR, 0, (char*)&desc, sizeof(struct module_desc));
+       if (ret != sizeof(struct module_desc)) {
+               mod_gpio_demo_eeprom_cs_release();
+               serial_write(serial_num, "EEPROM read error\r\n", 19);
+               return;
+       }
+       /* Send the content of the header */
+       serial_write(serial_num, "Module :\r\n", 10);
+       len = snprintf(buff, 16, "serial: %d, ", desc.serial_number);
+       len += snprintf((buff + len), 15, "ver: %d\r\n", desc.version);
+       len += snprintf((buff + len), 16, "cap: 0x%04x\r\n", desc.capabilities);
+       /* Get and send the module name */
+       if (desc.name_size >= DUMP_BUFF_SIZE) {
+               desc.name_size = DUMP_BUFF_SIZE - len - 3;
+       }
+       ret = eeprom_read(EEPROM_ADDR, desc.name_offset, (buff + len), desc.name_size);
+       if (ret == desc.name_size) {
+               len += ret;
+               len += snprintf((buff + len), 3, "\r\n");
+       }
+       ret = 0;
+       do {
+               ret += serial_write(serial_num, (buff + ret), (len - ret));
+       } while (ret < len);
+       mod_gpio_demo_eeprom_cs_release();
+}
+
+int module_desc_set(char* name, uint8_t module_version, uint16_t serial_num)
+{
+       int ret = 0;
+       struct module_desc desc = {
+               .serial_number = serial_num,
+               .version = module_version,
+               .capabilities = (UEXT_MOD_HAS_UART | UEXT_MOD_HAS_I2C | UEXT_MOD_HAS_SPI),
+               .name_offset = sizeof(struct module_desc),
+               .image_offset = 0,
+               .image_size = 0,
+       };
+
+       mod_gpio_demo_eeprom_cs_pull_low();
+       desc.name_size = strlen(name);
+       ret = eeprom_write(EEPROM_ADDR, 0, (char*)&desc, sizeof(struct module_desc));
+       if (ret != sizeof(struct module_desc)) {
+               mod_gpio_demo_eeprom_cs_release();
+               return -1;
+       }
+       ret += eeprom_write(EEPROM_ADDR, ret, name, desc.name_size);
+       mod_gpio_demo_eeprom_cs_release();
+       return ret;
+}
+
+
+void system_init()
+{
+       /* Stop the watchdog */
+       stop_watchdog(); /* Do it right now, before it gets a chance to break in */
+
+       /* Note: Brown-Out detection must be powered to operate the ADC. adc_on() will power
+        *  it back on if called after system_init() */
+       system_brown_out_detection_config(0);
+       system_set_default_power_state();
+       clock_config(SELECTED_FREQ);
+       set_pins(common_pins);
+       gpio_on();
+       status_led_config(&status_led_green, &status_led_red);
+       /* System tick timer MUST be configured and running in order to use the sleeping
+        * functions */
+       systick_timer_on(1); /* 1ms */
+       systick_start();
+}
+
+/* Define our fault handler. This one is not mandatory, the dummy fault handler
+ * will be used when it's not overridden here.
+ * Note : The default one does a simple infinite loop. If the watchdog is deactivated
+ * the system will hang.
+ */
+void fault_info(const char* name, uint32_t len)
+{
+       serial_write(0, name, len);
+       /* Wait for end of Tx */
+       serial_flush(0);
+       /* FIXME : Perform soft reset of the micro-controller ! */
+       while (1);
+}
+
+
+/***************************************************************************** */
+int main(void) {
+       system_init();
+       uart_on(0, 115200, NULL);
+
+       i2c_on(I2C_CLK_100KHz);
+
+       /* Set or read Module identification header in EEPROM */
+#ifdef EEPROM_WRITE
+       module_desc_set(MODULE_NAME, MODULE_VERSION, MODULE_SERIAL_NUM);
+#else
+       module_desc_dump(0);
+#endif
+
+       while (1) {
+               chenillard(250);
+       }
+       return 0;
+}
+
+
diff --git a/epaper/Makefile b/epaper/Makefile
new file mode 100644 (file)
index 0000000..e44d25f
--- /dev/null
@@ -0,0 +1,12 @@
+# Makefile for GPIO Demo Module apps
+
+NAME = $(shell basename $(CURDIR))
+
+.PHONY: $(NAME).bin
+$(NAME).bin:
+       @make -C ../.. --no-print-directory NAME=$(NAME) apps/$(NAME)/$@
+       cat $@ *.epaper > $(NAME).img
+
+clean mrproper:
+       @make -C ../.. --no-print-directory $@
+
diff --git a/epaper/README b/epaper/README
new file mode 100644 (file)
index 0000000..0f0ee8a
--- /dev/null
@@ -0,0 +1,45 @@
+E-paper example
+
+Copyright 2015 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/>.
+ *
+ *************************************************************************** */
+
+This example shows the support of the E-paper display from embedded Artists which is
+an adapter for Pervasive Display e-ink screen.
+
+In order to create an image for the display, make a 264x176 image, black and white.
+Using gimp, export as "Raw data image" (*.data).
+In the popup, select "Standard (R, V, B)" and "R, V, B (normal)".
+
+Then use the programm from the image_converter sub-directory to convert to e-paper
+format. (Use the Makefile in the sub-directory to compile).
+
+And use:
+./bw_raw_data_gimp_to_bw_epaper  input.data  output.epaper
+
+Current Makefile appends all raw images (*.epaper) to the firmware binary (epaper.bin)
+to generate the new binary which you should upload: epaper.img
+
+Current main only handles two images.
+Pressing the ISP button toggles between the images.
+
+Data received on UART0 is displayed on the first line when either of '\r', '\n' or '\0' is
+received.
+The maximum size of the line is 33 characters for the 2.7" epaper deisplay.
+
+
diff --git a/epaper/Techno-Innov_bw_epaper.epaper b/epaper/Techno-Innov_bw_epaper.epaper
new file mode 100644 (file)
index 0000000..d76ebdb
Binary files /dev/null and b/epaper/Techno-Innov_bw_epaper.epaper differ
diff --git a/epaper/image_converter/.gitignore b/epaper/image_converter/.gitignore
new file mode 100644 (file)
index 0000000..cf7077d
--- /dev/null
@@ -0,0 +1,16 @@
+#
+# NOTE! Don't add files that are generated in specific
+# subdirectories here. Add them in the ".gitignore" file
+# in that subdirectory instead.
+#
+# NOTE! Please use 'git ls-files -i --exclude-standard'
+# command after changing this file, to see if there are
+# any tracked files which get ignored after the change.
+#
+# Normal rules
+#
+*.o
+*.d
+*/objs/*
+tags
+bw_raw_data_gimp_to_bw_epaper
diff --git a/epaper/image_converter/Makefile b/epaper/image_converter/Makefile
new file mode 100644 (file)
index 0000000..aedb22f
--- /dev/null
@@ -0,0 +1,32 @@
+#CROSS_COMPILE ?= arm-linux-gnueabihf-
+CC = $(CROSS_COMPILE)gcc
+
+CFLAGS = -Wall -O2 -Wextra
+
+EXEC = bw_raw_data_gimp_to_bw_epaper
+
+all: $(EXEC)
+
+
+OBJDIR = objs
+SRC = $(shell find . -name \*.c)
+OBJS = ${SRC:%.c=${OBJDIR}/%.o}
+INCLUDES = includes/
+
+${OBJDIR}/%.o: %.c
+       @mkdir -p $(dir $@)
+       @echo "-- compiling" $<
+       @$(CC) -MMD -MP -MF ${OBJDIR}/$*.d $(CFLAGS) $< -c -o $@ -I$(INCLUDES)
+
+$(EXEC): $(OBJS)
+       @echo "Linking $@ ..."
+       @$(CC) $(LDFLAGS) -o $@ $(OBJS)
+       @echo Done.
+
+
+clean:
+       find ${OBJDIR} -name "*.o" -exec rm {} \;
+       find ${OBJDIR} -name "*.d" -exec rm {} \;
+
+mrproper: clean
+       rm -f $(EXEC)
diff --git a/epaper/image_converter/convert.c b/epaper/image_converter/convert.c
new file mode 100644 (file)
index 0000000..2934418
--- /dev/null
@@ -0,0 +1,37 @@
+#include <stdio.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <unistd.h>
+
+
+int main(int argc, char** argv)
+{
+       int source_fd = -1;
+       int dest_fd = -1;
+       char inbuff[8];
+
+       if (argc < 2) {
+               printf("Usage: %s input_file output_file\n", argv[0]);
+       }
+
+       source_fd = open(argv[1], O_RDONLY);
+       dest_fd = open(argv[2], (O_RDWR | O_CREAT), (S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH));
+
+       if ((source_fd < 0) || (dest_fd < 0)) {
+               printf("unable to open input or output file\n");
+       }
+
+       while (read(source_fd, inbuff, 8) == 8) {
+               int i = 0;
+               char outbuff = 0;
+               for (i = 0; i < 8; i++) {
+                       outbuff |= ((inbuff[i] & 0x01) << i);
+               }
+               write(dest_fd, &outbuff, 1);
+       }
+
+       close(source_fd);
+       close(dest_fd);
+
+       return 0;
+}
diff --git a/epaper/main.c b/epaper/main.c
new file mode 100644 (file)
index 0000000..7633ea5
--- /dev/null
@@ -0,0 +1,261 @@
+/****************************************************************************
+ *   apps/epaper/main.c
+ *
+ * e-paper example
+ *
+ * Copyright 2013-2015 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/>.
+ *
+ *************************************************************************** */
+
+
+#include <stdint.h>
+#include "core/lpc_regs_12xx.h"
+#include "core/lpc_core_cm0.h"
+#include "core/pio.h"
+#include "core/system.h"
+#include "core/systick.h"
+#include "lib/stdio.h"
+#include "drivers/serial.h"
+#include "drivers/gpio.h"
+#include "drivers/timers.h"
+#include "extdrv/status_led.h"
+#include "drivers/ssp.h"
+
+#include "extdrv/epaper.h"
+#include "lib/font.h"
+
+#define MODULE_VERSION    0x04
+#define MODULE_NAME "GPIO Demo Module"
+
+
+#define SELECTED_FREQ  FREQ_SEL_48MHz
+
+/***************************************************************************** */
+/* Pins configuration */
+/* pins blocks are passed to set_pins() for pins configuration.
+ * Unused pin blocks can be removed safely with the corresponding set_pins() call
+ * All pins blocks may be safelly merged in a single block for single set_pins() call..
+ */
+const struct pio_config common_pins[] = {
+       /* UART 0 */
+       { LPC_UART0_RX_PIO_0_1,  LPC_IO_DIGITAL },
+       { LPC_UART0_TX_PIO_0_2,  LPC_IO_DIGITAL },
+       /* UART 1 */
+       { LPC_UART1_RX_PIO_0_8, LPC_IO_DIGITAL },
+       { LPC_UART1_TX_PIO_0_9, LPC_IO_DIGITAL },
+       /* SPI */
+       { LPC_SSP0_SCLK_PIO_0_14, LPC_IO_DIGITAL },
+       { LPC_SSP0_MOSI_PIO_0_17, LPC_IO_DIGITAL },
+       { LPC_SSP0_MISO_PIO_0_16, LPC_IO_DIGITAL },
+       /* PWM */
+#define LPC_TIMER_PIN_CONFIG   (LPC_IO_MODE_PULL_UP | LPC_IO_DIGITAL | LPC_IO_DRIVE_HIGHCURENT)
+       { LPC_TIMER_32B0_M1_PIO_0_19, LPC_TIMER_PIN_CONFIG },
+       ARRAY_LAST_PIO,
+};
+
+const struct pio status_led_green = LPC_GPIO_1_4;
+const struct pio status_led_red = LPC_GPIO_1_5;
+
+const struct pio button = LPC_GPIO_0_12; /* ISP button */
+
+/*
+ * E-paper configuration, 2.7" size
+ *   see Pervasive display documentation (Doc. No. 4P008-00)
+ */
+#define LINE_SIZE  264
+struct epaper_definition epaper_def = {
+       .pin_reset = LPC_GPIO_0_20,
+       .pin_power_ctrl = LPC_GPIO_0_21,
+       .pin_discharge = LPC_GPIO_0_22,
+       .pin_border_ctrl = LPC_GPIO_0_23,
+       .pin_busy = LPC_GPIO_0_24,
+       /* SPI */
+       .pin_spi_cs = LPC_GPIO_0_15,
+       .spi_num = 0,
+       /* PWM */
+       .pwm_timer_num = LPC_TIMER_32B0,
+       .pwm_timer_conf = {
+               .mode = LPC_TIMER_MODE_PWM,
+               /* pin PIO0_19 is channel 1 - PWM cycle control on channel 3 */
+               .config = { LPC_PWM_CHANNEL_ENABLE(1), 3, 0, 0 },
+               .match = { 0, 60, 0, 120 }, /* 50% duty cycle on channel 1, approx 200 KHz whith 48MHz clock */
+       },
+       .pixels_per_line = LINE_SIZE,
+       .bytes_per_line = (LINE_SIZE / 8),
+       .lines = 176,
+       .bytes_per_scan = (176 / 4),
+       .channel = {0x00, 0x00, 0x00, 0x7F, 0xFF, 0xFE, 0x00, 0x00},  /* Reg 0x01 */
+       .gate_source_level = 0x00,  /* Reg 0x04 */
+       .stage_time = 630,
+       .line_termination_required = 1,
+};
+
+
+/***************************************************************************** */
+void system_init()
+{
+       /* Stop the watchdog */
+       stop_watchdog(); /* Do it right now, before it gets a chance to break in */
+
+       /* Note: Brown-Out detection must be powered to operate the ADC. adc_on() will power
+        *  it back on if called after system_init() */
+       system_brown_out_detection_config(0);
+       system_set_default_power_state();
+       clock_config(SELECTED_FREQ);
+       set_pins(common_pins);
+       gpio_on();
+       status_led_config(&status_led_green, &status_led_red);
+       /* System tick timer MUST be configured and running in order to use the sleeping
+        * functions */
+       systick_timer_on(1); /* 1ms */
+       systick_start();
+}
+
+/* Define our fault handler. This one is not mandatory, the dummy fault handler
+ * will be used when it's not overridden here.
+ * Note : The default one does a simple infinite loop. If the watchdog is deactivated
+ * the system will hang.
+ */
+void fault_info(const char* name, uint32_t len)
+{
+       serial_write(1, name, len);
+       /* Wait for end of Tx */
+       serial_flush(1);
+       /* FIXME : Perform soft reset of the micro-controller ! */
+       while (1);
+}
+
+static volatile uint8_t white_request = 0;
+void button_request(uint32_t gpio) {
+    white_request = 1;
+}
+
+extern unsigned int _sram_base;
+extern unsigned int _end_text;
+extern unsigned int _end_data;
+
+
+#define TEXT_LENGTH_MAX 33
+static volatile uint8_t display_text_buff[TEXT_LENGTH_MAX];
+static volatile uint8_t update_text = 0;
+void recv_text(uint8_t c)
+{
+       static uint8_t idx = 0;
+       static uint8_t rx_buff[TEXT_LENGTH_MAX];
+       rx_buff[idx++] = c;
+       if ((c == '\0') || (c == '\r') || (c == '\n')) {
+               update_text = 1;
+               rx_buff[idx++] = '\0';
+               memcpy((void*)display_text_buff, rx_buff, idx);
+               idx = 0;
+       }
+}
+
+void build_line(uint8_t* img_buff, uint8_t* text)
+{
+       int i = 0, line = 0;
+       int len = strlen((char*)text);
+
+       for (i = 0; i < len; i++) {
+               uint8_t tile = (text[i] > first_font_char) ? (text[i] - first_font_char) : 0;
+               uint8_t* tile_data = (uint8_t*)(&font[tile]);
+               for (line = 0; line < 8; line++) {
+                       img_buff[ (line * epaper_def.bytes_per_line) + i ] = tile_data[7 - line];
+               }
+       }
+}
+
+
+/* FIXME :
+ * Actual font data is stored in "human drawing order", but must be sent in revers bit order.
+ * This function takes care of bit reversal for each font byte once and for all.
+ * This should be done on the font file for execution efficiency and code size, but would make
+ *   font update harder.
+ */
+void fix_font(uint64_t* font_64, uint8_t size)
+{
+       int i = 0;
+       uint32_t* f = (uint32_t*)font_64;
+       size = size * 2;
+       for (i = 0; i < size; i++) {
+               // swap odd and even bits
+               f[i] = ((f[i] >> 1) & 0x55555555) | ((f[i] & 0x55555555) << 1);
+               // swap consecutive pairs
+               f[i] = ((f[i] >> 2) & 0x33333333) | ((f[i] & 0x33333333) << 2);
+               // swap nibbles ... 
+               f[i] = ((f[i] >> 4) & 0x0F0F0F0F) | ((f[i] & 0x0F0F0F0F) << 4);
+       }
+}
+
+/***************************************************************************** */
+#define BUFF_LEN 60
+int main(void) {
+
+       system_init();
+       uart_on(0, 115200, recv_text);
+       ssp_master_on(0, LPC_SSP_FRAME_SPI, 8, 8*1000*1000); /* bus_num, frame_type, data_width, rate */
+       set_gpio_callback(button_request, &button, EDGE_RISING);
+       status_led(none);
+
+       /* E-Paper */
+       epaper_config(&epaper_def);
+       /* Font fix */
+       fix_font(font, NB_FONT_TILES);
+
+       while (1) {
+               if (white_request == 1) {
+                       static int img_num = 0;
+                       uint8_t* images = (uint8_t*)(&_end_text + (&_end_data - &_sram_base));
+                       uint8_t* image = (images + ((img_num % 2) * (epaper_def.bytes_per_line * epaper_def.lines)));
+
+                       status_led(green_only);
+
+                       epaper_on();
+                       /* Blank screen */
+                       epaper_uniform_display(0xAA); /* White */
+                       /*      epaper_uniform_display(0xFF); */ /* Black */
+                       /* Send image */
+                       epaper_send_frame(image, epaper_normal);
+                       epaper_off();
+
+                       white_request = 0;
+                       update_text = 1;
+                       img_num = ((img_num + 1) % 2);
+               }
+
+               if (update_text == 1) {
+                       uint8_t white_line[LINE_SIZE] = {0};  /* ((LINE_SIZE / 8) * 8) */
+                       uint8_t buffer_line[LINE_SIZE] = {0}; /* ((LINE_SIZE / 8) * 8) */
+
+                       build_line(buffer_line, (uint8_t*)display_text_buff);
+
+                       epaper_on();
+                       /* Blank text line */
+                       epaper_send_partial_frame(white_line, 0, 8, epaper_normal);
+                       /* Real text line */
+                       epaper_send_partial_frame(buffer_line, 0, 8, epaper_normal);
+                       epaper_off();
+
+                       update_text = 0;
+               }
+       }
+       return 0;
+}
+
+
+
+
diff --git a/epaper/tibug_bw_epaper.epaper b/epaper/tibug_bw_epaper.epaper
new file mode 100644 (file)
index 0000000..a7730ed
Binary files /dev/null and b/epaper/tibug_bw_epaper.epaper differ
diff --git a/gpio_intr/Makefile b/gpio_intr/Makefile
new file mode 100644 (file)
index 0000000..91407f3
--- /dev/null
@@ -0,0 +1,10 @@
+# Makefile for GPIO Demo Module apps
+
+NAME = $(shell basename $(CURDIR))
+
+.PHONY: $(NAME).bin
+$(NAME).bin:
+       @make -C ../.. --no-print-directory NAME=$(NAME) apps/$(NAME)/$@
+
+clean mrproper:
+       @make -C ../.. --no-print-directory $@
diff --git a/gpio_intr/README b/gpio_intr/README
new file mode 100644 (file)
index 0000000..e6657af
--- /dev/null
@@ -0,0 +1,25 @@
+GPIO interrupt Example
+
+Copyright 2015 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/>.
+ *
+ *************************************************************************** */
+
+This example shows the support of the gpio interrupts from an external button.
+
+The "chenillard" is playing in an endless loop, but a release of the ISP button will
+stop it for 5 seconds.
diff --git a/gpio_intr/main.c b/gpio_intr/main.c
new file mode 100644 (file)
index 0000000..7ea3ad0
--- /dev/null
@@ -0,0 +1,124 @@
+/****************************************************************************
+ *   apps/gpio_intr/main.c
+ *
+ * GPIO interrupt example
+ *
+ * Copyright 2013-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/>.
+ *
+ *************************************************************************** */
+
+/* ISP button release disables the chenillard for 5 seconds */
+
+#include <stdint.h>
+#include "core/lpc_regs_12xx.h"
+#include "core/lpc_core_cm0.h"
+#include "core/pio.h"
+#include "core/system.h"
+#include "core/systick.h"
+#include "lib/stdio.h"
+#include "drivers/serial.h"
+#include "drivers/gpio.h"
+#include "extdrv/status_led.h"
+
+
+#define MODULE_VERSION    0x04
+#define MODULE_NAME "GPIO Demo Module"
+
+
+#define SELECTED_FREQ  FREQ_SEL_48MHz
+
+/***************************************************************************** */
+/* Pins configuration */
+/* pins blocks are passed to set_pins() for pins configuration.
+ * Unused pin blocks can be removed safely with the corresponding set_pins() call
+ * All pins blocks may be safelly merged in a single block for single set_pins() call..
+ */
+const struct pio_config common_pins[] = {
+       /* UART 0 */
+       { LPC_UART0_RX_PIO_0_1,  LPC_IO_DIGITAL },
+       { LPC_UART0_TX_PIO_0_2,  LPC_IO_DIGITAL },
+       ARRAY_LAST_PIO,
+};
+
+const struct pio status_led_green = LPC_GPIO_1_4;
+const struct pio status_led_red = LPC_GPIO_1_5;
+
+const struct pio button = LPC_GPIO_0_12; /* ISP button */
+
+
+/***************************************************************************** */
+void system_init()
+{
+       /* Stop the watchdog */
+       stop_watchdog(); /* Do it right now, before it gets a chance to break in */
+
+       /* Note: Brown-Out detection must be powered to operate the ADC. adc_on() will power
+        *  it back on if called after system_init() */
+       system_brown_out_detection_config(0);
+       system_set_default_power_state();
+       clock_config(SELECTED_FREQ);
+       set_pins(common_pins);
+       gpio_on();
+       status_led_config(&status_led_green, &status_led_red);
+       /* System tick timer MUST be configured and running in order to use the sleeping
+        * functions */
+       systick_timer_on(1); /* 1ms */
+       systick_start();
+}
+
+/* Define our fault handler. This one is not mandatory, the dummy fault handler
+ * will be used when it's not overridden here.
+ * Note : The default one does a simple infinite loop. If the watchdog is deactivated
+ * the system will hang.
+ */
+void fault_info(const char* name, uint32_t len)
+{
+       serial_write(0, name, len);
+       /* Wait for end of Tx */
+       serial_flush(0);
+       /* FIXME : Perform soft reset of the micro-controller ! */
+       while (1);
+}
+
+
+uint8_t chenillard_activation_request = 0;
+void activate_chenillard(uint32_t gpio) {
+       chenillard_activation_request = 1;
+}
+
+
+/***************************************************************************** */
+int main(void) {
+       system_init();
+       uart_on(0, 115200, NULL);
+
+       /* Activate the chenillard on Rising edge (button release) */
+       set_gpio_callback(activate_chenillard, &button, EDGE_RISING);
+
+       while (1) {
+               chenillard(250);
+               if (chenillard_activation_request == 1) {
+                       status_led(none);
+                       msleep(5000);
+                       chenillard_activation_request = 0;
+               }
+       }
+       return 0;
+}
+
+
+
diff --git a/i2c_temp/Makefile b/i2c_temp/Makefile
new file mode 100644 (file)
index 0000000..91407f3
--- /dev/null
@@ -0,0 +1,10 @@
+# Makefile for GPIO Demo Module apps
+
+NAME = $(shell basename $(CURDIR))
+
+.PHONY: $(NAME).bin
+$(NAME).bin:
+       @make -C ../.. --no-print-directory NAME=$(NAME) apps/$(NAME)/$@
+
+clean mrproper:
+       @make -C ../.. --no-print-directory $@
diff --git a/i2c_temp/README b/i2c_temp/README
new file mode 100644 (file)
index 0000000..621b7ed
--- /dev/null
@@ -0,0 +1,33 @@
+TMP101 I2C temperature sensor example
+
+Copyright 2013 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/>.
+ *
+ *************************************************************************** */
+
+This example shows the support of the TMP101 I2C temperature sensor used on the
+GPIO Demo module.
+
+
+Periodic temperature conversions (decimal velue and raw conversion value) are
+sent on UART0 using the following frame format :
+Temp read: 27,3 - raw: 0x1b60.
+
+FIXME : Add support for the alert pin of the TMP101 temperature sensor.
+Send an alert on both UART0 and UART1
+Stop the chenillard as long as the alert condition is present.
+
diff --git a/i2c_temp/main.c b/i2c_temp/main.c
new file mode 100644 (file)
index 0000000..8f3f3ff
--- /dev/null
@@ -0,0 +1,167 @@
+/****************************************************************************
+ *   apps/i2c_temp/main.c
+ *
+ * TMP101 I2C temperature sensor example
+ *
+ * Copyright 2013-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/>.
+ *
+ *************************************************************************** */
+
+
+#include <stdint.h>
+#include "core/lpc_regs_12xx.h"
+#include "core/lpc_core_cm0.h"
+#include "core/pio.h"
+#include "core/system.h"
+#include "core/systick.h"
+#include "lib/stdio.h"
+#include "drivers/i2c.h"
+#include "drivers/serial.h"
+#include "drivers/gpio.h"
+#include "extdrv/status_led.h"
+#include "extdrv/tmp101_temp_sensor.h"
+
+
+#define MODULE_VERSION    0x04
+#define MODULE_NAME "GPIO Demo Module"
+
+
+#define SELECTED_FREQ  FREQ_SEL_48MHz
+
+/***************************************************************************** */
+/* Pins configuration */
+/* pins blocks are passed to set_pins() for pins configuration.
+ * Unused pin blocks can be removed safely with the corresponding set_pins() call
+ * All pins blocks may be safelly merged in a single block for single set_pins() call..
+ */
+const struct pio_config common_pins[] = {
+       /* UART 0 */
+       { LPC_UART0_RX_PIO_0_1,  LPC_IO_DIGITAL },
+       { LPC_UART0_TX_PIO_0_2,  LPC_IO_DIGITAL },
+       /* I2C 0 */
+       { LPC_I2C0_SCL_PIO_0_10, (LPC_IO_DIGITAL | LPC_IO_OPEN_DRAIN_ENABLE) },
+       { LPC_I2C0_SDA_PIO_0_11, (LPC_IO_DIGITAL | LPC_IO_OPEN_DRAIN_ENABLE) },
+       ARRAY_LAST_PIO,
+};
+
+#define TMP101_ADDR  0x94
+struct tmp101_sensor_config tmp101_sensor = {
+       .addr = TMP101_ADDR,
+       .resolution = TMP_RES_ELEVEN_BITS,
+};
+
+const struct pio temp_alert = LPC_GPIO_0_7;
+
+const struct pio status_led_green = LPC_GPIO_1_4;
+const struct pio status_led_red = LPC_GPIO_1_5;
+
+/***************************************************************************** */
+/* Temperature */
+/* The Temperature Alert pin is on GPIO Port 0, pin 7 (PIO0_7) */
+/* The I2C Temperature sensor is at address 0x94 */
+void WAKEUP_Handler(void)
+{
+}
+
+void temp_config(uint8_t addr, int uart_num)
+{
+       int ret = 0;
+
+       /* Temp Alert */
+       config_gpio(&temp_alert, LPC_IO_MODE_PULL_UP, GPIO_DIR_IN, 0);
+       /* FIXME : add a callback on temp_alert edge */
+
+       /* Temp sensor */
+       ret = tmp101_sensor_config(&tmp101_sensor);
+       if (ret != 0) {
+               serial_write(uart_num, "Temp config error\r\n", 19);
+       }
+}
+
+void temp_display(uint8_t addr, int uart_num)
+{
+       char buff[40];
+       uint16_t raw = 0;
+       int deci_degrees = 0;
+       int len = 0;
+
+       tmp101_sensor_start_conversion(&tmp101_sensor);
+       msleep(250); /* Wait for the end of the conversion : 40ms */
+       len = tmp101_sensor_read(&tmp101_sensor, &raw, &deci_degrees);
+       if (len != 0) {
+               serial_write(uart_num, "Temp read error\r\n", 19);
+       } else {
+               len = snprintf(buff, 40, "Temp read: %d,%d - raw: 0x%04x.\r\n",
+                               (deci_degrees/10), (deci_degrees%10), raw);
+               serial_write(uart_num, buff, len);
+       }
+}
+
+
+/***************************************************************************** */
+void system_init()
+{
+       /* Stop the watchdog */
+       stop_watchdog(); /* Do it right now, before it gets a chance to break in */
+
+       /* Note: Brown-Out detection must be powered to operate the ADC. adc_on() will power
+        *  it back on if called after system_init() */
+       system_brown_out_detection_config(0);
+       system_set_default_power_state();
+       clock_config(SELECTED_FREQ);
+       set_pins(common_pins);
+       gpio_on();
+       status_led_config(&status_led_green, &status_led_red);
+       /* System tick timer MUST be configured and running in order to use the sleeping
+        * functions */
+       systick_timer_on(1); /* 1ms */
+       systick_start();
+}
+
+/* Define our fault handler. This one is not mandatory, the dummy fault handler
+ * will be used when it's not overridden here.
+ * Note : The default one does a simple infinite loop. If the watchdog is deactivated
+ * the system will hang.
+ */
+void fault_info(const char* name, uint32_t len)
+{
+       serial_write(1, name, len);
+       /* Wait for end of Tx */
+       serial_flush(1);
+       /* FIXME : Perform soft reset of the micro-controller ! */
+       while (1);
+}
+
+
+
+/***************************************************************************** */
+int main(void) {
+       system_init();
+       uart_on(0, 115200, NULL);
+
+       i2c_on(I2C_CLK_100KHz);
+
+       /* Configure onboard temp sensor */
+       temp_config(TMP101_ADDR, 0);
+
+       while (1) {
+               chenillard(250);
+               temp_display(TMP101_ADDR, 0);
+       }
+       return 0;
+}
+
diff --git a/lcd_char/Makefile b/lcd_char/Makefile
new file mode 100644 (file)
index 0000000..86e0d12
--- /dev/null
@@ -0,0 +1,11 @@
+# Makefile for GPIO Demo Module apps
+
+NAME = $(shell basename $(CURDIR))
+
+.PHONY: $(NAME).bin
+$(NAME).bin:
+       @make -C ../.. --no-print-directory NAME=$(NAME) apps/$(NAME)/$@
+
+clean mrproper:
+       @make -C ../.. --no-print-directory $@
+
diff --git a/lcd_char/README b/lcd_char/README
new file mode 100644 (file)
index 0000000..1c64cd2
--- /dev/null
@@ -0,0 +1,47 @@
+LCD Character display example
+
+Copyright 2015 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/>.
+ *
+ *************************************************************************** */
+
+This example shows the support of the LCD Character displays compatible with the
+Hitachi HD44780 driver.
+This demo application has also been used to test the Max31588 thermocouple to digital
+converter.
+
+
+The demo uses two LCD Character displays, one 20x4 characters connected using 8 data
+lines, and a second 16x2 characters display connected using 4 data lines.
+
+Upon start both displays should print "Techno-Innov".
+
+Data received on UART0 is displayed on the "next" line of the first display as it is
+received, unless it starts with character '/', in which case it goes on the second line
+of the second display.
+
+The first line of the second display is used to display the temperature read from the
+Max31588 over SPI.
+
+
+Note :
+Some functions of the lcd_char library have not been tested.
+The "busy bit" reading is not working properly (always returned as not busy).
+Data reading has not been tested.
+Moving the cursor or the display has not been tested either.
+
+
diff --git a/lcd_char/main.c b/lcd_char/main.c
new file mode 100644 (file)
index 0000000..c1859a8
--- /dev/null
@@ -0,0 +1,275 @@
+/****************************************************************************
+ *   apps/lcd_char/main.c
+ *
+ * LCD Character Display example
+ *
+ * Copyright 2013-2015 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/>.
+ *
+ *************************************************************************** */
+
+
+#include <stdint.h>
+#include "core/lpc_regs_12xx.h"
+#include "core/lpc_core_cm0.h"
+#include "core/pio.h"
+#include "core/system.h"
+#include "core/systick.h"
+#include "lib/stdio.h"
+#include "drivers/serial.h"
+#include "drivers/gpio.h"
+#include "drivers/timers.h"
+#include "extdrv/status_led.h"
+#include "drivers/ssp.h"
+
+#include "extdrv/lcd_char.h"
+#include "extdrv/max31855_thermocouple.h"
+
+#define MODULE_VERSION    0x04
+#define MODULE_NAME "GPIO Demo Module"
+
+
+#define SELECTED_FREQ  FREQ_SEL_48MHz
+
+/***************************************************************************** */
+/* Pins configuration */
+/* pins blocks are passed to set_pins() for pins configuration.
+ * Unused pin blocks can be removed safely with the corresponding set_pins() call
+ * All pins blocks may be safelly merged in a single block for single set_pins() call..
+ */
+const struct pio_config common_pins[] = {
+       /* UART 0 */
+       { LPC_UART0_RX_PIO_0_1,  LPC_IO_DIGITAL },
+       { LPC_UART0_TX_PIO_0_2,  LPC_IO_DIGITAL },
+       /* SPI */
+       { LPC_SSP0_SCLK_PIO_0_14, LPC_IO_DIGITAL },
+       { LPC_SSP0_MOSI_PIO_0_17, LPC_IO_DIGITAL },
+       { LPC_SSP0_MISO_PIO_0_16, LPC_IO_DIGITAL },
+       ARRAY_LAST_PIO,
+};
+
+const struct pio status_led_green = LPC_GPIO_1_4;
+const struct pio status_led_red = LPC_GPIO_1_5;
+
+const struct pio button = LPC_GPIO_0_12; /* ISP button */
+
+
+/* Thermocouple reading */
+const struct max31855_sensor_config thermo = {
+       .ssp_bus_num = 0,
+       .chip_select = LPC_GPIO_0_15,
+};
+
+/*
+ * LCD Character display configuration
+ */
+#define TEXT_LENGTH_MAX_LCD_ONE 20
+struct lcdc_definition lcd_one = {
+       /* Control pins */
+       .pin_reg_sel = LPC_GPIO_0_19,
+       .pin_rw_sel = LPC_GPIO_0_20,
+       .pin_enable = LPC_GPIO_0_21,
+       /* Data pins */
+       .data_pins = {
+               LPC_GPIO_0_22,
+               LPC_GPIO_0_23,
+               LPC_GPIO_0_24,
+               LPC_GPIO_0_25,
+               LPC_GPIO_0_26,
+               LPC_GPIO_0_27,
+               LPC_GPIO_0_28,
+               LPC_GPIO_0_29,
+       },
+       .nb_lines = 4,
+       .bytes_per_line = TEXT_LENGTH_MAX_LCD_ONE,
+       .eight_bits_mode = LCDC_DATA_IS_EIGTH_BITS,
+       .font_size = LCDC_FONT_EIGHT_DOTS,
+       .increment_type = LCDC_MODE_INCREMENT,
+       .auto_display_shift = 0,
+};
+#define TEXT_LENGTH_MAX_LCD_TWO 16
+struct lcdc_definition lcd_two = {
+       /* Control pins */
+       .pin_reg_sel = LPC_GPIO_0_3,
+       .pin_rw_sel = LPC_GPIO_0_4,
+       .pin_enable = LPC_GPIO_0_5,
+       /* Data pins */
+       .data_pins = {
+               LPC_GPIO_0_6,
+               LPC_GPIO_0_7,
+               LPC_GPIO_0_8,
+               LPC_GPIO_0_9,
+       },
+       .nb_lines = 2,
+       .bytes_per_line = TEXT_LENGTH_MAX_LCD_TWO,
+       .eight_bits_mode = LCDC_DATA_IS_FOUR_BITS,
+       .font_size = LCDC_FONT_EIGHT_DOTS,
+       .increment_type = LCDC_MODE_INCREMENT,
+       .auto_display_shift = 0,
+};
+
+
+/***************************************************************************** */
+void system_init()
+{
+       /* Stop the watchdog */
+       stop_watchdog(); /* Do it right now, before it gets a chance to break in */
+
+       /* Note: Brown-Out detection must be powered to operate the ADC. adc_on() will power
+        *  it back on if called after system_init() */
+       system_brown_out_detection_config(0);
+       system_set_default_power_state();
+       clock_config(SELECTED_FREQ);
+       set_pins(common_pins);
+       gpio_on();
+       status_led_config(&status_led_green, &status_led_red);
+       /* System tick timer MUST be configured and running in order to use the sleeping
+        * functions */
+       systick_timer_on(1); /* 1ms */
+       systick_start();
+}
+
+/* Define our fault handler. This one is not mandatory, the dummy fault handler
+ * will be used when it's not overridden here.
+ * Note : The default one does a simple infinite loop. If the watchdog is deactivated
+ * the system will hang.
+ */
+void fault_info(const char* name, uint32_t len)
+{
+       serial_write(1, name, len);
+       /* Wait for end of Tx */
+       serial_flush(1);
+       /* FIXME : Perform soft reset of the micro-controller ! */
+       while (1);
+}
+
+static volatile uint8_t clear_request = 0;
+void button_request(uint32_t gpio) {
+    clear_request = 1;
+}
+
+
+static volatile uint8_t display_text_buff[TEXT_LENGTH_MAX_LCD_ONE];
+static volatile uint8_t update_text = 0;
+void recv_text(uint8_t c)
+{
+       static uint8_t idx = 0;
+       static uint8_t rx_buff[TEXT_LENGTH_MAX_LCD_ONE];
+       rx_buff[idx++] = c;
+       if ((c == '\0') || (c == '\r') || (c == '\n')) {
+               update_text = 1;
+               rx_buff[(idx - 1)] = ' ';
+               memcpy((void*)display_text_buff, rx_buff, idx);
+               idx = 0;
+       }
+       if (idx >= TEXT_LENGTH_MAX_LCD_ONE) {
+               idx = 0;
+       }
+}
+
+
+#define TEMP_CYCLE_DELAY 1000
+/***************************************************************************** */
+int main(void)
+{
+       int get_temp = 0;
+
+       system_init();
+       uart_on(0, 115200, recv_text);
+       ssp_master_on(thermo.ssp_bus_num, LPC_SSP_FRAME_SPI, 8, 4*1000*1000);
+       set_gpio_callback(button_request, &button, EDGE_RISING);
+       status_led(none);
+
+       /* Thermocouple configuration */
+       max31855_sensor_config(&thermo);
+       uprintf(0, "Thermocouple config OK\n");
+
+       /* LCD Character display configuration */
+       lcdc_config(&lcd_one);
+       lcdc_init(&lcd_one);
+       lcdc_config(&lcd_two);
+       lcdc_init(&lcd_two);
+       uprintf(0, "Displays Init OK\n");
+
+       /* Turn displays on */
+       lcdc_on_off(&lcd_one, 1, 0, 0); /* ON, Cursor underline off, Cursor blink off */
+       lcdc_on_off(&lcd_two, 1, 0, 1); /* ON, Cursor underline off, Cursor blink on */
+       uprintf(0, "Displays ON\n");
+
+       lcdc_move_cursor_home(&lcd_one);
+       lcdc_move_cursor_home(&lcd_two);
+       uprintf(0, "Cursors at home\n");
+
+       lcdc_send_data_line(&lcd_one, 0, (uint8_t*)"Techno-Innov", 12);
+       lcdc_send_data_line(&lcd_two, 1, (uint8_t*)"Techno-Innov", 12);
+       memset((void*)display_text_buff, ' ', TEXT_LENGTH_MAX_LCD_ONE);
+
+       while (1) {
+               if (clear_request == 1) {
+                       /* Only clear LCD "one" */
+                       lcdc_clear(&lcd_one);
+                       lcdc_move_cursor_home(&lcd_one);
+                       clear_request = 0;
+               }
+               if (update_text == 1) {
+                       static int line_lcd_one = 1;
+                       static int line_lcd_two = 1;
+                       if (display_text_buff[0] != '/') {
+                               lcdc_send_data_line(&lcd_one, line_lcd_one, (uint8_t*)display_text_buff, lcd_one.bytes_per_line);
+                               memset((void*)display_text_buff, ' ', TEXT_LENGTH_MAX_LCD_ONE);
+                               line_lcd_one++;
+                               if (line_lcd_one >= lcd_one.nb_lines) {
+                                       line_lcd_one = 0;
+                               }
+                       } else {
+                               lcdc_send_data_line(&lcd_two, line_lcd_two, (uint8_t*)display_text_buff, lcd_two.bytes_per_line);
+                               memset((void*)display_text_buff, ' ', TEXT_LENGTH_MAX_LCD_ONE);
+                               line_lcd_two++;
+                               if (line_lcd_two >= lcd_two.nb_lines) {
+                                       line_lcd_two = 1; /* Keep first line for temperature */
+                               }
+                       }
+                       update_text = 0;
+               }
+               if (get_temp++ == TEMP_CYCLE_DELAY) {
+                       int centi_degrees = 0, ret = 0;
+                       ret = max31855_sensor_read(&thermo, NULL, &centi_degrees);
+                       if (ret != 0) {
+                               lcdc_send_data_line(&lcd_two, 0, (uint8_t*)"Temp err", 8);
+                       } else {
+                               char buff[10];
+                               int abs_centi = centi_degrees;
+                               int len = 0;
+                               if (centi_degrees < 0) {
+                                       abs_centi = -centi_degrees;
+                               }
+                               len = snprintf(buff, 10, "% 4d.%02d ", (centi_degrees / 100), (abs_centi % 100));
+                               buff[len] = ' ';
+                               lcdc_send_data_line(&lcd_two, 0, (uint8_t*)buff, 8);
+                               lcdc_write(&lcd_two, 0xDF);
+                               lcdc_write(&lcd_two, 'C');
+                       }
+                       get_temp = 0;
+               } else {
+                       msleep(1);
+               }
+       }
+       return 0;
+}
+
+
+
+
diff --git a/ledstrip/Makefile b/ledstrip/Makefile
new file mode 100644 (file)
index 0000000..91407f3
--- /dev/null
@@ -0,0 +1,10 @@
+# Makefile for GPIO Demo Module apps
+
+NAME = $(shell basename $(CURDIR))
+
+.PHONY: $(NAME).bin
+$(NAME).bin:
+       @make -C ../.. --no-print-directory NAME=$(NAME) apps/$(NAME)/$@
+
+clean mrproper:
+       @make -C ../.. --no-print-directory $@
diff --git a/ledstrip/README b/ledstrip/README
new file mode 100644 (file)
index 0000000..180ed2e
--- /dev/null
@@ -0,0 +1,43 @@
+WS2812 Chainable leds example
+
+Copyright 2015 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/>.
+ *
+ *************************************************************************** */
+
+This example shows the support of the WS2812 chainable leds.
+It has been tested using a 60 leds strip from Adafruit.
+
+WS2812 external driver development is based on data found in the WS2812.pdf
+datasheet provided by Adafruit : https://www.adafruit.com/datasheets/WS2812.pdf
+
+
+The external driver (extdrv/ws2812.[ch]) provides an internal buffer which size
+is defined in extdrv/ws2812.h (NB_LEDS)
+This buffer is filled using ws2812_set_pixel(), and the led values are sent to
+the led strip using ws2812_send_frame().
+
+
+This example uses the driver and adds some filling functions selected by the
+module ISP button or commands received on UART0 serial line.
+Leds data is generated by the filling functions either from pre-defined
+patterns or using ADC samples or UART received data.
+Not all functions have been implemented yet.
+
+TODO : Implement other functions / modes.
+
+
diff --git a/ledstrip/main.c b/ledstrip/main.c
new file mode 100644 (file)
index 0000000..0b830f0
--- /dev/null
@@ -0,0 +1,194 @@
+/****************************************************************************
+ *   apps/ledstrip/main.c
+ *
+ * WS2812 Chainable leds example using Adafruit les strip
+ *
+ * Copyright 2013-2015 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/>.
+ *
+ *************************************************************************** */
+
+
+#include <stdint.h>
+#include "core/lpc_regs_12xx.h"
+#include "core/lpc_core_cm0.h"
+#include "core/pio.h"
+#include "core/system.h"
+#include "core/systick.h"
+#include "lib/stdio.h"
+#include "drivers/serial.h"
+#include "drivers/gpio.h"
+#include "drivers/adc.h"
+#include "extdrv/status_led.h"
+
+#include "extdrv/ws2812.h"
+
+#define MODULE_VERSION    0x04
+#define MODULE_NAME "GPIO Demo Module"
+
+
+#define SELECTED_FREQ  FREQ_SEL_48MHz
+
+/***************************************************************************** */
+/* Pins configuration */
+/* pins blocks are passed to set_pins() for pins configuration.
+ * Unused pin blocks can be removed safely with the corresponding set_pins() call
+ * All pins blocks may be safelly merged in a single block for single set_pins() call..
+ */
+const struct pio_config common_pins[] = {
+       /* UART 0 */
+       { LPC_UART0_RX_PIO_0_1,  LPC_IO_DIGITAL },
+       { LPC_UART0_TX_PIO_0_2,  LPC_IO_DIGITAL },
+       /* UART 1 */
+       { LPC_UART1_RX_PIO_0_8, LPC_IO_DIGITAL },
+       { LPC_UART1_TX_PIO_0_9, LPC_IO_DIGITAL },
+       /* SPI */
+       { LPC_SSP0_SCLK_PIO_0_14, LPC_IO_DIGITAL },
+       { LPC_SSP0_MOSI_PIO_0_17, LPC_IO_DIGITAL },
+       { LPC_SSP0_MISO_PIO_0_16, LPC_IO_DIGITAL },
+       /* ADC */
+       { LPC_ADC_AD0_PIO_0_30, LPC_IO_ANALOG },
+       { LPC_ADC_AD1_PIO_0_31, LPC_IO_ANALOG },
+       { LPC_ADC_AD2_PIO_1_0,  LPC_IO_ANALOG },
+       /* GPIO */
+       { LPC_GPIO_0_19, (LPC_IO_MODE_PULL_UP | LPC_IO_DIGITAL) },
+       ARRAY_LAST_PIO,
+};
+
+const struct pio status_led_green = LPC_GPIO_1_4;
+const struct pio status_led_red = LPC_GPIO_1_5;
+
+const struct pio button = LPC_GPIO_0_12; /* ISP button */
+const struct pio ws2812_data_out_pin = LPC_GPIO_0_19; /* Led control data pin */
+
+
+/***************************************************************************** */
+void system_init()
+{
+       /* Stop the watchdog */
+       stop_watchdog(); /* Do it right now, before it gets a chance to break in */
+
+       /* Note: Brown-Out detection must be powered to operate the ADC. adc_on() will power
+        *  it back on if called after system_init() */
+       system_brown_out_detection_config(0);
+       system_set_default_power_state();
+       clock_config(SELECTED_FREQ);
+       set_pins(common_pins);
+       gpio_on();
+       status_led_config(&status_led_green, &status_led_red);
+       /* System tick timer MUST be configured and running in order to use the sleeping
+        * functions */
+       systick_timer_on(1); /* 1ms */
+       systick_start();
+}
+
+/* Define our fault handler. This one is not mandatory, the dummy fault handler
+ * will be used when it's not overridden here.
+ * Note : The default one does a simple infinite loop. If the watchdog is deactivated
+ * the system will hang.
+ */
+void fault_info(const char* name, uint32_t len)
+{
+       serial_write(1, name, len);
+       /* Wait for end of Tx */
+       serial_flush(1);
+       /* FIXME : Perform soft reset of the micro-controller ! */
+       while (1);
+}
+
+
+enum all_modes {
+       adc_colors = 0,
+       random_colors,
+       single_color_grade_red,
+       single_color_grade_green,
+       single_color_grade_blue,
+       color_grade_red_from_adc,
+       color_grade_green_from_adc,
+       color_grade_blue_from_adc,
+       full_grade,
+       moving_dot_adc_color,
+       serial_controlled,
+       white,
+};
+static volatile uint8_t new_mode = 0;
+void button_request(uint32_t gpio) {
+    new_mode++;
+}
+
+
+/* This mode reads values from ADC[0:2] every 150ms and uses the values to set the leds.
+ * Pixels are updated when all pixel are set from ADC input.
+ */
+void mode_adc_colors(void)
+{
+       static uint8_t pixel = 0;
+       uint16_t red = 0, green = 0, blue = 0;
+
+       /* Get ADC values */
+       adc_get_value(&red, LPC_ADC_NUM(0));
+       adc_get_value(&green, LPC_ADC_NUM(1));
+       adc_get_value(&blue, LPC_ADC_NUM(2));
+       /* Set one pixel */
+       ws2812_set_pixel(pixel++, ((red >> 2) & 0xFF), ((green >> 2) & 0xFF), ((blue >> 2) & 0xFF));
+       /* Give some time for the ADC value to change (potentiometers should be connected to ADC inputs) */
+       msleep(150);
+       /* give some feedback that something is going on */
+       status_led(green_toggle);
+       /* Buffer full, send it ! */
+       if (pixel >= NB_LEDS) {
+               ws2812_send_frame(0);
+               pixel = 0;
+       }
+}
+
+void strip_control(uint8_t c)
+{
+}
+
+/***************************************************************************** */
+int main(void)
+{
+
+       system_init();
+       uart_on(0, 115200, strip_control);
+       set_gpio_callback(button_request, &button, EDGE_RISING);
+       status_led(none);
+
+       /* ADC for potentiometer color settings */
+       adc_on();
+       adc_start_burst_conversion(LPC_ADC_CHANNEL(0) | LPC_ADC_CHANNEL(1) | LPC_ADC_CHANNEL(2));
+
+       /* Led strip configuration */
+       ws2812_config(&ws2812_data_out_pin);
+
+       while (1) {
+               switch (new_mode) {
+                       case adc_colors:
+                               mode_adc_colors();
+                               break;
+                       default:
+                               ws2812_stop();
+                               msleep(1500);
+                               new_mode = 0;
+               }
+       }
+       return 0;
+}
+
+
+
+
diff --git a/ultrasonic_sensor/Makefile b/ultrasonic_sensor/Makefile
new file mode 100644 (file)
index 0000000..91407f3
--- /dev/null
@@ -0,0 +1,10 @@
+# Makefile for GPIO Demo Module apps
+
+NAME = $(shell basename $(CURDIR))
+
+.PHONY: $(NAME).bin
+$(NAME).bin:
+       @make -C ../.. --no-print-directory NAME=$(NAME) apps/$(NAME)/$@
+
+clean mrproper:
+       @make -C ../.. --no-print-directory $@
diff --git a/ultrasonic_sensor/README b/ultrasonic_sensor/README
new file mode 100644 (file)
index 0000000..3152862
--- /dev/null
@@ -0,0 +1,29 @@
+Ultrasonic range measurement module Example
+
+Copyright 2015 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/>.
+ *
+ *************************************************************************** */
+
+This example shows the support of the ultrasonic range measurement module from Seeed studio :
+http://www.seeedstudio.com/wiki/index.php?title=Ultra_Sonic_range_measurement_module
+
+The distance is sent over UART0 every 50ms.
+
+Note tha for the tests the ultrasonic module is powered at 3.3V and that the right distance
+is given by dividing the pulse width by 29 instead of 58 (value given on the ultrasonic
+module wiki page).
diff --git a/ultrasonic_sensor/main.c b/ultrasonic_sensor/main.c
new file mode 100644 (file)
index 0000000..2a6112a
--- /dev/null
@@ -0,0 +1,174 @@
+/****************************************************************************
+ *   apps/ultrasonic_sensor/main.c
+ *
+ * Ultrasonic range measurement example
+ *
+ * Copyright 2013-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/>.
+ *
+ *************************************************************************** */
+
+/* Support for ultrasonic range measurement module.
+ * Refer to readme file for further information.
+ */
+
+#include <stdint.h>
+#include "core/lpc_regs_12xx.h"
+#include "core/lpc_core_cm0.h"
+#include "core/pio.h"
+#include "core/system.h"
+#include "core/systick.h"
+#include "lib/stdio.h"
+#include "drivers/serial.h"
+#include "drivers/gpio.h"
+#include "extdrv/status_led.h"
+
+
+#define MODULE_VERSION    0x04
+#define MODULE_NAME "GPIO Demo Module"
+
+
+#define SELECTED_FREQ  FREQ_SEL_48MHz
+
+/***************************************************************************** */
+/* Pins configuration */
+/* pins blocks are passed to set_pins() for pins configuration.
+ * Unused pin blocks can be removed safely with the corresponding set_pins() call
+ * All pins blocks may be safelly merged in a single block for single set_pins() call..
+ */
+const struct pio_config common_pins[] = {
+       /* UART 0 */
+       { LPC_UART0_RX_PIO_0_1,  LPC_IO_DIGITAL },
+       { LPC_UART0_TX_PIO_0_2,  LPC_IO_DIGITAL },
+       ARRAY_LAST_PIO,
+};
+
+const struct pio status_led_green = LPC_GPIO_1_4;
+const struct pio status_led_red = LPC_GPIO_1_5;
+
+const struct pio sensor = LPC_GPIO_0_7; /* Ultrasonic sensor signal */
+
+
+/***************************************************************************** */
+void system_init()
+{
+       /* Stop the watchdog */
+       stop_watchdog(); /* Do it right now, before it gets a chance to break in */
+
+       /* Note: Brown-Out detection must be powered to operate the ADC. adc_on() will power
+        *  it back on if called after system_init() */
+       system_brown_out_detection_config(0);
+       system_set_default_power_state();
+       clock_config(SELECTED_FREQ);
+       set_pins(common_pins);
+       gpio_on();
+       status_led_config(&status_led_green, &status_led_red);
+       /* System tick timer MUST be configured and running in order to use the sleeping
+        * functions */
+       systick_timer_on(1); /* 1ms */
+       systick_start();
+}
+
+/* Define our fault handler. This one is not mandatory, the dummy fault handler
+ * will be used when it's not overridden here.
+ * Note : The default one does a simple infinite loop. If the watchdog is deactivated
+ * the system will hang.
+ */
+void fault_info(const char* name, uint32_t len)
+{
+       serial_write(0, name, len);
+       /* Wait for end of Tx */
+       serial_flush(0);
+       /* FIXME : Perform soft reset of the micro-controller ! */
+       while (1);
+}
+
+
+/* Note that clock cycles counter wraps every 89 seconds with system clock running at 48 MHz */
+static volatile uint32_t pulse_start = 0;  /* Clock cycles counter upon echo start */
+static volatile uint32_t pulse_end = 0;    /* Clock cycles counter upon echo end */
+static volatile uint32_t pulse_duration = 0;
+void pulse_feedback(uint32_t gpio) {
+       static uint32_t pulse_state = 0;
+       if (pulse_state == 0) {
+               pulse_start = systick_get_clock_cycles();
+               pulse_state = 1;
+       } else {
+               pulse_end = systick_get_clock_cycles();
+               if (pulse_end > pulse_start) {
+                       pulse_duration = (pulse_end - pulse_start);
+               } else {
+                       pulse_duration = (0xFFFFFFFF - pulse_start);
+                       pulse_duration += pulse_end;
+               }
+               pulse_state = 0;
+       }
+}
+
+/* Delay between measures should be at least 50ms  */
+#define DELAY 50
+
+/***************************************************************************** */
+int main(void) {
+       char buff[60];
+       int len = 0;
+       uint32_t next_time = 0;
+       uint32_t delay = 0;
+
+       system_init();
+       uart_on(0, 115200, NULL);
+       next_time = systick_get_tick_count();
+
+       /* Callback on pulse start and end */
+       set_gpio_callback(pulse_feedback, &sensor, EDGES_BOTH);
+
+       while (1) {
+               uint32_t distance = 0;
+
+               /* Initiate distance mesurement */
+               gpio_dir_out(sensor);
+               gpio_clear(sensor);
+               usleep(10);
+               gpio_set(sensor);
+               usleep(10);
+               gpio_clear(sensor);
+               gpio_dir_in(sensor);
+               pulse_duration = 0;
+
+               /* Wait for value to be available */
+               while (pulse_duration == 0) {
+                       msleep(1);
+               }
+               /* Convert pulse width in us to distance in mm */
+               distance = ((pulse_duration * 10) / (get_main_clock() / (1000*1000)));
+               distance = distance / 29;
+               /* Send value on serial */
+               len = snprintf(buff, 60, "dist: %dmm\n", distance);
+               serial_write(0, buff, len);
+       
+               /* And wait at least 50ms between loops */
+               delay = next_time - systick_get_tick_count();
+               if (delay > DELAY) {
+                       delay = DELAY;
+               }
+               msleep(delay);
+               next_time += DELAY;
+       }
+       return 0;
+}
+
+
+