diff --git a/Makefile b/Makefile index a54fe04..6283f02 100644 --- a/Makefile +++ b/Makefile @@ -33,6 +33,7 @@ OPT = 3 C_FLAGS += -O$(OPT) -g$(OPT) C_FLAGS += -Wall -Werror C_FLAGS += -ffunction-sections -fdata-sections -fno-strict-aliasing +C_FLAGS += -DPLATFORM_$(PLATFORM) LIBS += c nosys m diff --git a/include/board.h b/include/board.h new file mode 100644 index 0000000..462b778 --- /dev/null +++ b/include/board.h @@ -0,0 +1,8 @@ +#ifndef __BOARD_H__ +#define __BOARD_H__ + +#if defined(BOARD_PCA10040) + #include "platform/nrf52/nrf52-dk.h" +#endif + +#endif diff --git a/include/delay.h b/include/delay.h new file mode 100644 index 0000000..3dc2836 --- /dev/null +++ b/include/delay.h @@ -0,0 +1,10 @@ +#ifndef __DELAY_H__ +#define __DELAY_H__ + +#if defined(PLATFORM_nrf52) + #include "nrf_delay.h" + + #define delay_ms nrf_delay_ms +#endif + +#endif diff --git a/include/driver.h b/include/driver.h new file mode 100644 index 0000000..f594acd --- /dev/null +++ b/include/driver.h @@ -0,0 +1,34 @@ +#ifndef __DRIVER_H__ +#define __DRIVER_H__ + +#include + +struct driver; + +typedef int (*fp_open_t)(const struct driver *); +typedef int (*fp_close_t)(const struct driver *); +typedef int (*fp_read_t)(const struct driver *, char *, unsigned int); +typedef int (*fp_write_t)(const struct driver *, const char *, unsigned int); +typedef int (*fp_ioctl_t)(const struct driver *, unsigned int, unsigned int argc, va_list); + +struct driver_fp { + fp_open_t open; + fp_close_t close; + fp_read_t read; + fp_write_t write; + fp_ioctl_t ioctl; +}; + +struct driver { + const char *name; + const struct driver_fp *fp; + const void *dev; +}; + +int drv_open(const struct driver *drv); +int drv_close(const struct driver *drv); +int drv_read(const struct driver *drv, char *buffer, unsigned int length); +int drv_write(const struct driver *drv, const char *buffer, unsigned int length); +int drv_ioctl(const struct driver *drv, unsigned int cmd, unsigned int argc, ...); + +#endif diff --git a/include/gpio.h b/include/gpio.h new file mode 100644 index 0000000..a96e143 --- /dev/null +++ b/include/gpio.h @@ -0,0 +1,34 @@ +#ifndef __GPIO_H__ +#define __GPIO_H__ + +#include + +#include "driver.h" + +#define IOCTL_CMD_SET_DIRECTION 0 + +int gpio_open(const struct driver *drv); +int gpio_close(const struct driver *drv); + +int gpio_read(const struct driver *drv, char *buffer, unsigned int len); +int gpio_write(const struct driver *drv, const char *buffer, unsigned int len); + +enum direction { + IN = 0, + OUT +}; + +struct gpio { + int pin; + enum direction dir; +}; + +static const struct driver_fp gpio_fp = { + .open = gpio_open, + .close = gpio_close, + .read = gpio_read, + .write = gpio_write, + .ioctl = NULL +}; + +#endif diff --git a/include/platform/nrf52/nrf52-dk.h b/include/platform/nrf52/nrf52-dk.h new file mode 100644 index 0000000..473651c --- /dev/null +++ b/include/platform/nrf52/nrf52-dk.h @@ -0,0 +1,52 @@ +#ifndef __NRF52_DK_H__ +#define __NRF52_DK_H__ + +#include "driver.h" + +#include "gpio.h" + +// LED 1 +const struct gpio nrf_led_1 = { + .pin = 17, + .dir = OUT +}; +const struct driver led_1 = { + .name = "LED1", + .fp = &gpio_fp, + .dev = &nrf_led_1 +}; + +// LED 2 +const struct gpio nrf_led_2 = { + .pin = 18, + .dir = OUT +}; +const struct driver led_2 = { + .name = "LED2", + .fp = &gpio_fp, + .dev = &nrf_led_2 +}; + +// LED 3 +const struct gpio nrf_led_3 = { + .pin = 19, + .dir = OUT +}; +const struct driver led_3 = { + .name = "LED3", + .fp = &gpio_fp, + .dev = &nrf_led_3 +}; + +// LED 4 +const struct gpio nrf_led_4 = { + .pin = 20, + .dir = OUT +}; +const struct driver led_4 = { + .name = "LED4", + .fp = &gpio_fp, + .dev = &nrf_led_4 +}; + +#endif diff --git a/src/application/blinky/main.c b/src/application/blinky/main.c index 4cc92b0..23ba09c 100644 --- a/src/application/blinky/main.c +++ b/src/application/blinky/main.c @@ -1,77 +1,22 @@ -/** - * Copyright (c) 2014 - 2019, Nordic Semiconductor ASA - * - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without modification, - * are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, this - * list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form, except as embedded into a Nordic - * Semiconductor ASA integrated circuit in a product or a software update for - * such product, must reproduce the above copyright notice, this list of - * conditions and the following disclaimer in the documentation and/or other - * materials provided with the distribution. - * - * 3. Neither the name of Nordic Semiconductor ASA nor the names of its - * contributors may be used to endorse or promote products derived from this - * software without specific prior written permission. - * - * 4. This software, with or without modification, must only be used with a - * Nordic Semiconductor ASA integrated circuit. - * - * 5. Any software provided in binary form under this license must not be reverse - * engineered, decompiled, modified and/or disassembled. - * - * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS - * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES - * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE - * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT - * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - */ -/** @file - * - * @defgroup blinky_example_main main.c - * @{ - * @ingroup blinky_example - * @brief Blinky Example Application main file. - * - * This file contains the source code for a sample application to blink LEDs. - * - */ - #include #include -#include "nrf_delay.h" -#include "boards.h" -/** - * @brief Function for application main entry. - */ +#include "delay.h" +#include "board.h" + int main(void) { - /* Configure board. */ - bsp_board_init(BSP_INIT_LEDS); - - /* Toggle LEDs. */ - while (true) - { - for (int i = 0; i < LEDS_NUMBER; i++) - { - bsp_board_led_invert(i); - nrf_delay_ms(500); + unsigned int cnt[4] = {0, 0, 0, 0}; + const struct driver *leds[4] = {&led_1, &led_2, &led_3, &led_4}; + for(unsigned int i = 0; i < 4; i++) { + drv_open(leds[i]); + } + while(true) { + for(unsigned int i = 0; i < 4; i++) { + char c = (cnt[i]++ % 2) + 0x30; + drv_write(leds[i], &c, 1); + delay_ms(500); } } + return 0; } - -/** - *@} - **/ diff --git a/src/driver.c b/src/driver.c new file mode 100644 index 0000000..3892c47 --- /dev/null +++ b/src/driver.c @@ -0,0 +1,67 @@ +#include +#include + +#include "driver.h" + +int drv_open(const struct driver *drv) +{ + int res = -1; + assert(drv != NULL); + + if(drv->fp->open) { + res = drv->fp->open(drv); + } + + return res; +} + +int drv_close(const struct driver *drv) +{ + int res = -1; + assert(drv != NULL); + + if(drv->fp->close) { + res = drv->fp->close(drv); + } + + return res; +} + +int drv_read(const struct driver *drv, char *buffer, unsigned int length) +{ + int res = -1; + assert(drv != NULL); + + if(drv->fp->read) { + res = drv->fp->read(drv, buffer, length); + } + + return res; +} + +int drv_write(const struct driver *drv, const char *buffer, unsigned int length) +{ + int res = -1; + assert(drv != NULL); + + if(drv->fp->write) { + res = drv->fp->write(drv, buffer, length); + } + + return res; +} + +int drv_ioctl(const struct driver *drv, unsigned int cmd, unsigned int argc, ...) +{ + int res = -1; + assert(drv != NULL); + + if(drv->fp->ioctl) { + va_list args; + va_start(args, argc); + res = drv->fp->ioctl(drv, cmd, argc, args); + va_end(args); + } + + return res; +} diff --git a/src/platform/nrf52/gpio.c b/src/platform/nrf52/gpio.c new file mode 100644 index 0000000..328a58e --- /dev/null +++ b/src/platform/nrf52/gpio.c @@ -0,0 +1,63 @@ +#include +#include +#include + +#include "gpio.h" + +#include "nrf_gpio.h" + +int gpio_open(const struct driver *drv) +{ + assert(NULL != drv); + + struct gpio *this = (struct gpio *)(drv->dev); + + if(this->dir == OUT) { + nrf_gpio_cfg_output((uint32_t)(this->pin)); + nrf_gpio_pin_clear(this->pin); + } + // FIXME: implement input configuration + + return 0; +} + +int gpio_close(const struct driver *drv) +{ + assert(NULL != drv); + + struct gpio *this = (struct gpio *)(drv->dev); + nrf_gpio_pin_clear(this->pin); + + return 0; +} + +int gpio_read(const struct driver *drv, char *buffer, unsigned int len) +{ + assert(NULL != drv); + + if(len == 0) { + return 0; + } + + struct gpio *this = (struct gpio *)(drv->dev); + + uint32_t value = nrf_gpio_pin_read(this->pin); + buffer[0] = value + 0x30; // ascii convert + + return 1; +} + +int gpio_write(const struct driver *drv, const char *buffer, unsigned int len) +{ + assert((NULL != drv) && (NULL != buffer)); + + if(len == 0) { + return 0; + } + + struct gpio *this = (struct gpio *)(drv->dev); + + nrf_gpio_pin_write(this->pin, buffer[0] - 0x30); + + return 1; +}