--- /dev/null
+# 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 $@
--- /dev/null
+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.
--- /dev/null
+/****************************************************************************
+ * 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;
+}
+
+
+
--- /dev/null
+# 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 $@
--- /dev/null
+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
--- /dev/null
+/****************************************************************************
+ * 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;
+}
+
+
--- /dev/null
+# 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 $@
+
--- /dev/null
+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.
+
+
--- /dev/null
+#
+# 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
--- /dev/null
+#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)
--- /dev/null
+#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;
+}
--- /dev/null
+/****************************************************************************
+ * 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;
+}
+
+
+
+
--- /dev/null
+# 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 $@
--- /dev/null
+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.
--- /dev/null
+/****************************************************************************
+ * 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;
+}
+
+
+
--- /dev/null
+# 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 $@
--- /dev/null
+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.
+
--- /dev/null
+/****************************************************************************
+ * 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;
+}
+
--- /dev/null
+# 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 $@
+
--- /dev/null
+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.
+
+
--- /dev/null
+/****************************************************************************
+ * 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, ¢i_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;
+}
+
+
+
+
--- /dev/null
+# 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 $@
--- /dev/null
+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.
+
+
--- /dev/null
+/****************************************************************************
+ * 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;
+}
+
+
+
+
--- /dev/null
+# 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 $@
--- /dev/null
+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).
--- /dev/null
+/****************************************************************************
+ * 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;
+}
+
+
+