diff --git a/CMakeLists.txt b/CMakeLists.txt index 34a63b4..e370183 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -33,3 +33,8 @@ target_sources(app PRIVATE # src/acq/source.c # src/acq/timer.c ) + +add_compile_definitions( + BL_REVISION=2 + REVISION=2 +) \ No newline at end of file diff --git a/boards/arm/bloodlight_rev2/Kconfig.defconfig b/boards/arm/bloodlight_rev2/Kconfig.defconfig index 71d095e..3316915 100644 --- a/boards/arm/bloodlight_rev2/Kconfig.defconfig +++ b/boards/arm/bloodlight_rev2/Kconfig.defconfig @@ -14,6 +14,11 @@ config SPI_STM32_INTERRUPT endif + +config PRINTK + bool "Send printk() to console" + default y + config USB_DEVICE_VID hex "USB Vendor ID" default 0x0483 @@ -25,4 +30,5 @@ config USB_DEVICE_PID default 0x5740 depends on USB help - USB device product ID. MUST be configured by vendor. \ No newline at end of file + USB device product ID. MUST be configured by vendor. + diff --git a/src/led.c b/src/led.c index a4e57a7..5686ec0 100644 --- a/src/led.c +++ b/src/led.c @@ -17,8 +17,8 @@ #include #include -// #include -// #include +#include +#include #include "common/error.h" #include "common/util.h" @@ -46,24 +46,34 @@ #define LED_BR(pin) (LED_BS(pin) << 16) #define LED_BSRR(port) ((port) + 0x18) +/* The devicetree node identifier for the "led0" alias. */ +#define STATUS_NODE DT_ALIAS(statusled) + +#if DT_NODE_HAS_STATUS(STATUS_NODE, okay) +#define STATUS_LED DT_GPIO_LABEL(STATUS_NODE, gpios) +#define STATUS_PIN DT_GPIO_PIN(STATUS_NODE, gpios) +#define STATUS_FLAGS DT_GPIO_FLAGS(STATUS_NODE, gpios) +#else +/* A build error here means your board isn't set up to blink an LED. */ +#error "Unsupported board: statusled devicetree alias is not defined" +#define STATUS_LED "" +#define STATUS_PIN 0 +#define STATUS_FLAGS 0 +#endif + unsigned bl_led_count; volatile unsigned bl_led_active; bl_led_channel_t bl_led_channel[BL_LED_COUNT]; -/** GPIO ports used for LEDs */ +/** GPIO ports used for LEDs *//* enum led_port { LED_PORT_A, LED_PORT_B, LED_PORT_C, -}; - -/* HACK: define GPIOx values to allow build */ -#define GPIOA 1 -#define GPIOB 2 -#define GPIOC 3 +};*/ /** GPIO port addresses */ -static const uint32_t led_port[] = { +static const GPIO_TypeDef * led_port[] = { [LED_PORT_A] = GPIOA, [LED_PORT_B] = GPIOB, [LED_PORT_C] = GPIOC, @@ -128,26 +138,80 @@ static inline uint16_t bl_led__get_pin_mask( return pin_mask; } -static inline void bl_led__gpio_mode_setup(enum led_port port) +/** GPIO binding function, needed to avoid variables holding desired node value*/ +const struct device * gpio_binding (enum led_port port) { + const struct device * gpio; + switch (port) { + case LED_PORT_A: + gpio = device_get_binding(DT_LABEL(DT_NODELABEL(gpioa))); + if (gpio == NULL) { + printk("GPIOA binding error\n"); + } + break; + case LED_PORT_B: + gpio = device_get_binding(DT_LABEL(DT_NODELABEL(gpiob))); + if (gpio == NULL) { + printk("GPIOB binding error\n"); + } + break; + case LED_PORT_C: + gpio = device_get_binding(DT_LABEL(DT_NODELABEL(gpioc))); + if (gpio == NULL) { + printk("GPIOC binding error\n"); + } + break; + default: + gpio = NULL; //check NULL + break; + } + return gpio; +} + + + +static inline void bl_led__gpio_mode_setup() { - /* - gpio_mode_setup(led_port[port], GPIO_MODE_OUTPUT, GPIO_PUPD_NONE, - bl_led__get_pin_mask(port, 0xffff)); - */ + //Get the gpio bindings + const struct device * gpioa = gpio_binding(LED_PORT_A); + const struct device * gpiob = gpio_binding(LED_PORT_B); + const struct device * gpioc = gpio_binding(LED_PORT_C); + + //Configure the pins connected to leds as output. + for (int led = 0; led < BL_LED_COUNT ; led++) { + switch (led_table[led].port_idx){ + case LED_PORT_A: + if (gpio_pin_configure(gpioa, led_table[led].pin, GPIO_OUTPUT) !=0){ + printk("Error configuring port\n"); + } + break; + case LED_PORT_B: + if (gpio_pin_configure(gpiob, led_table[led].pin, GPIO_OUTPUT) !=0){ + printk("Error configuring port\n"); + } + break; + case LED_PORT_C: + if (gpio_pin_configure(gpioc, led_table[led].pin, GPIO_OUTPUT) !=0){ + printk("Error configuring port\n"); + } + break; + } + + } } /* Exported function, documented in led.h */ void bl_led_init(void) { - /* - rcc_periph_clock_enable(RCC_GPIOA); - rcc_periph_clock_enable(RCC_GPIOB); - rcc_periph_clock_enable(RCC_GPIOC); - */ + for (uint8_t port = 0 ; port < sizeof(led_port)/sizeof(led_port[0]); port++) { + const struct device * gpio = gpio_binding(port); - bl_led__gpio_mode_setup(LED_PORT_A); - bl_led__gpio_mode_setup(LED_PORT_B); - bl_led__gpio_mode_setup(LED_PORT_C); + const clock_control_subsys_t *subsys = gpio -> config; + if (clock_control_on(gpio, *subsys) < 0) { + printk("Error: Can't turn clock on\n"); + } + }; + + bl_led__gpio_mode_setup(); bl_led_set(0x0000); } @@ -162,10 +226,14 @@ static inline void bl_led__set( * 2. Making bl_led_init() cache the clear masks so they can be reused * here. */ - /* - gpio_clear(led_port[port], bl_led__get_pin_mask(port, 0xffff)); - gpio_set(led_port[port], bl_led__get_pin_mask(port, led_mask)); - */ + typedef uint32_t gpio_port_pins_t; + const struct device * gpio; + + gpio_port_pins_t pinmask = bl_led__get_pin_mask(port, 0xffff); + gpio = gpio_binding(port); + gpio_port_set_masked(gpio, pinmask, 0); + pinmask = bl_led__get_pin_mask(port, led_mask); + gpio_port_set_masked(gpio, pinmask, 0xffff); } /* Exported function, documented in led.h */ @@ -181,15 +249,23 @@ enum bl_error bl_led_set(uint16_t led_mask) void bl_led_status_set(bool enable) { #if (BL_REVISION >= 2) + const struct device * gpio; + + gpio=device_get_binding(STATUS_LED); + if (gpio == NULL) { + return; + } + if (enable) { - /* - gpio_mode_setup(GPIOB, GPIO_MODE_OUTPUT, GPIO_PUPD_NONE, GPIO7); - gpio_clear(GPIOB, GPIO7); - */ + if (gpio_pin_configure(gpio, STATUS_PIN, GPIO_OUTPUT_LOW | STATUS_FLAGS) < 0) { + printk("Error: failed to enable status pin\n"); + return; + } } else { - /* - gpio_mode_setup(GPIOB, GPIO_MODE_INPUT, GPIO_PUPD_NONE, GPIO7); - */ + if (gpio_pin_configure(gpio, STATUS_PIN, GPIO_INPUT | STATUS_FLAGS) < 0) { + printk("Error: failed to disable status pin\n"); + return; + } } #else BL_UNUSED(enable); @@ -215,7 +291,7 @@ enum bl_error bl_led_setup(uint16_t led_mask) active->src_mask = LED_SRC(bl_acq_channel_get_source(i)); active->gpios = LED_BS(led_table[i].pin); active->gpior = LED_BR(led_table[i].pin); - active->gpio_bsrr = LED_BSRR(led_port[led_table[i].port_idx]); + active->gpio_bsrr = LED_BSRR(led_port[led_table[i].port_idx]->BSRR); led_mask &= ~(1U << i); @@ -243,9 +319,14 @@ static inline void bl_led__gpio_set(unsigned led) /* Exported function, documented in led.h */ enum bl_error bl_led_loop(void) { - /* - gpio_set(GPIOB, GPIO12); - */ + const struct device * gpio; + + gpio = device_get_binding(DT_LABEL(DT_NODELABEL(gpiob))); + if (gpio_pin_configure(gpio, 12, GPIO_OUTPUT | STATUS_FLAGS) < 0) { + printk("Error: failed to configure pin 12\n"); + return BL_ERROR_HARDWARE_CONFLICT; + } + gpio_port_set_bits(gpio, 12); //Commented to avoid depending on spi, to be uncommented /*if (bl_spi_mode == BL_ACQ_SPI_NONE) { bl_led__gpio_clear(bl_led_active); @@ -262,7 +343,7 @@ enum bl_error bl_led_loop(void) led_to_send = 0; bl_spi_send(bl_led_channel[led_to_send].led); - gpio_clear(GPIOB, GPIO12); + gpio_port_clear_bits(gpio, GPIO12); } else if (bl_spi_mode == BL_ACQ_SPI_NONE) { bl_led__gpio_set(bl_led_active); }*/ @@ -271,7 +352,7 @@ enum bl_error bl_led_loop(void) } /* Exported function, documented in led.h */ -uint32_t bl_led_get_port(uint8_t led) +const GPIO_TypeDef * bl_led_get_port(uint8_t led) { return led_port[led_table[led].port_idx]; } diff --git a/src/led.h b/src/led.h index cb53b4c..2103013 100644 --- a/src/led.h +++ b/src/led.h @@ -23,6 +23,8 @@ #include "common/error.h" #include "common/led.h" +#include + /** LED source globals */ typedef struct { uint8_t led; @@ -32,6 +34,11 @@ typedef struct { uint32_t gpio_bsrr; } bl_led_channel_t; +enum led_port { + LED_PORT_A, + LED_PORT_B, + LED_PORT_C, +}; extern unsigned bl_led_count; extern volatile unsigned bl_led_active; @@ -73,7 +80,7 @@ enum bl_error bl_led_loop(void); * \param[in] led LED index to be checked * \return \ref GPIO port for specified LED */ -uint32_t bl_led_get_port(uint8_t led); +const GPIO_TypeDef * bl_led_get_port(uint8_t led); /** * Get the corresponding GPIO pin number for specified LED @@ -83,5 +90,12 @@ uint32_t bl_led_get_port(uint8_t led); */ uint16_t bl_led_get_gpio(uint8_t led); +/** + * Get the corresponding GPIO port device binding for the specified enum led_port value + * + * \param[in] port Desired gpio port's enum led_port value + * \return \ref GPIO port device binding + */ +const struct device * gpio_binding (enum led_port port); #endif diff --git a/src/spi.c b/src/spi.c index 02897db..11f738e 100644 --- a/src/spi.c +++ b/src/spi.c @@ -223,6 +223,8 @@ void bl_spi_daughter_poll(void) static uint32_t gpioport, old_gpioport; static uint16_t gpio, old_gpio; static bool to_next = false; + const struct device * oldgpio_binding; + const struct device * gpio_binding; if (SPI_SR(SPI2) & SPI_SR_RXNE) { bl_spi_mode = BL_ACQ_SPI_DAUGHTER; @@ -232,8 +234,10 @@ void bl_spi_daughter_poll(void) to_next = true; } if (to_next && gpio_get(GPIOB, GPIO12)) { - gpio_clear(old_gpioport, old_gpio); - gpio_set(gpioport, gpio); + gpio_binding = gpio_binding(gpioport); + oldgpio_binding= gpio_binding(old_gpioport); + gpio_port_clear_bits(oldgpio_binding, old_gpio); + gpio_port_set_bits(gpio_binding, gpio); old_gpioport = gpioport; old_gpio = gpio; to_next = false; diff --git a/tests/led/CMakeLists.txt b/tests/led/CMakeLists.txt index 06ebc6f..22c4485 100644 --- a/tests/led/CMakeLists.txt +++ b/tests/led/CMakeLists.txt @@ -15,6 +15,11 @@ zephyr_include_directories(${CMAKE_SOURCE_DIR}/../..) project(led_test) target_sources(app PRIVATE - main.c + bloodlight_based.c ../../src/led.c ) + +add_compile_definitions( + BL_REVISION=2 + REVISION=2 +) \ No newline at end of file diff --git a/tests/led/bloodlight_based.c b/tests/led/bloodlight_based.c new file mode 100644 index 0000000..ecbbd26 --- /dev/null +++ b/tests/led/bloodlight_based.c @@ -0,0 +1,237 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "../../common/led.h" +#include "../../src/led.h" + +#define SLEEP_TIME_MS 1000 +#define LOOPS 10 +/* The devicetree node identifier for the "led0" alias. */ +#define STATUS_NODE DT_ALIAS(statusled) + +#if DT_NODE_HAS_STATUS(STATUS_NODE, okay) +#define STATUS_LED DT_GPIO_LABEL(STATUS_NODE, gpios) +#define STATUS_PIN DT_GPIO_PIN(STATUS_NODE, gpios) +#define STATUS_FLAGS DT_GPIO_FLAGS(STATUS_NODE, gpios) +#else +/* A build error here means your board isn't set up to blink an LED. */ +#error "Unsupported board: led0 devicetree alias is not defined" +#define STATUS_LED "" +#define STATUS_PIN 0 +#define STATUS_FLAGS 0 +#endif + +void main (void) { + const struct device *dev = device_get_binding( + CONFIG_UART_CONSOLE_ON_DEV_NAME); + uint32_t dtr = 0; + + if (usb_enable(NULL)) { + return; + } + + while (!dtr) { + uart_line_ctrl_get(dev, UART_LINE_CTRL_DTR, &dtr); + } + + if (strlen(CONFIG_UART_CONSOLE_ON_DEV_NAME) != + strlen("CDC_ACM_0") || + strncmp(CONFIG_UART_CONSOLE_ON_DEV_NAME, "CDC_ACM_0", + strlen(CONFIG_UART_CONSOLE_ON_DEV_NAME))) { + printk("Error: Console device name is not USB ACM\n"); + + return; + } + + printf("\n*****Starting LED APIs tests****\n"); + + printf("\nTesting bl_led_get_port\n"); + for (int led = 0; led < BL_LED_COUNT; led++){ + switch (led) + { + #if (BL_REVISION == 1) + case 4: + case 5: + case 6: + case 7: + __ASSERT(((GPIO_TypeDef *) GPIOA_BASE) == bl_led_get_port(led), "Invalid port value in led %i\n", led); + break; + case 0: + case 1: + case 2: + case 3: + case 11: + case 12: + case 13: + case 14: + case 15: + __ASSERT(((GPIO_TypeDef *) GPIOB_BASE) == bl_led_get_port(led), "Invalid port value in led %i\n", led); + break; + case 8: + case 9: + case 10: + __ASSERT(((GPIO_TypeDef *) GPIOC_BASE) == bl_led_get_port(led), "Invalid port value in led %i\n", led); + break; + #else + case 1: + case 4: + case 5: + case 6: + case 7: + case 11: + case 13: + case 14: + case 15: + __ASSERT(((GPIO_TypeDef *) GPIOA_BASE) == bl_led_get_port(led), "Invalid port value in led %i\n", led); + break; + case 2: + case 9: + case 10: + case 12: + __ASSERT(((GPIO_TypeDef *) GPIOB_BASE) == bl_led_get_port(led), "Invalid port value in led %i\n", led); + break; + case 0: + case 3: + case 8: + __ASSERT(((GPIO_TypeDef *) GPIOC_BASE) == bl_led_get_port(led), "Invalid port value in led %i\n", led); + break; + #endif + } + } + printf("\nSuccess testing bl_led_get_port\n"); + + + printf("\nTesting bl_led_get_gpio\n"); + for (int led = 0; led < BL_LED_COUNT; led++){ + switch (led) + { + #if (BL_REVISION == 1) + case 0: + __ASSERT((1U << 1) == bl_led_get_gpio(led), "Invalid pin value in led %i\n", led); + break; + case 1: + __ASSERT((1U << 2) == bl_led_get_gpio(led), "Invalid pin value in led %i\n", led); + break; + case 2: + __ASSERT((1U << 10) == bl_led_get_gpio(led), "Invalid pin value in led %i\n", led); + break; + case 3: + __ASSERT((1U << 11) == bl_led_get_gpio(led), "Invalid pin value in led %i\n", led); + break; + case 4: + __ASSERT((1U << 8) == bl_led_get_gpio(led), "Invalid pin value in led %i\n", led); + break; + case 5: + __ASSERT((1U << 9) == bl_led_get_gpio(led), "Invalid pin value in led %i\n", led); + break; + case 6: + __ASSERT((1U << 10) == bl_led_get_gpio(led), "Invalid pin value in led %i\n", led); + break; + case 7: + __ASSERT((1U << 15) == bl_led_get_gpio(led), "Invalid pin value in led %i\n", led); + break; + case 8: + __ASSERT((1U << 13) == bl_led_get_gpio(led), "Invalid pin value in led %i\n", led); + break; + case 9: + __ASSERT((1U << 14) == bl_led_get_gpio(led), "Invalid pin value in led %i\n", led); + break; + case 10: + __ASSERT((1U << 15) == bl_led_get_gpio(led), "Invalid pin value in led %i\n", led); + break; + case 11: + __ASSERT((1U << 9) == bl_led_get_gpio(led), "Invalid pin value in led %i\n", led); + break; + case 12: + __ASSERT((1U << 8) == bl_led_get_gpio(led), "Invalid pin value in led %i\n", led); + break; + case 13: + __ASSERT((1U << 7) == bl_led_get_gpio(led), "Invalid pin value in led %i\n", led); + break; + case 14: + __ASSERT((1U << 6) == bl_led_get_gpio(led), "Invalid pin value in led %i\n", led); + break; + case 15: + __ASSERT((1U << 5) == bl_led_get_gpio(led), "Invalid pin value in led %i\n", led); + break; + #else + case 0: + __ASSERT((1U << 14) == bl_led_get_gpio(led), "Invalid pin value in led %i\n", led); + break; + case 1: + __ASSERT((1U << 10) == bl_led_get_gpio(led), "Invalid pin value in led %i\n", led); + break; + case 2: + __ASSERT((1U << 11) == bl_led_get_gpio(led), "Invalid pin value in led %i\n", led); + break; + case 3: + __ASSERT((1U << 13) == bl_led_get_gpio(led), "Invalid pin value in led %i\n", led); + break; + case 4: + __ASSERT((1U << 6) == bl_led_get_gpio(led), "Invalid pin value in led %i\n", led); + break; + case 5: + __ASSERT((1U << 8) == bl_led_get_gpio(led), "Invalid pin value in led %i\n", led); + break; + case 6: + __ASSERT((1U << 9) == bl_led_get_gpio(led), "Invalid pin value in led %i\n", led); + break; + case 7: + __ASSERT((1U << 5) == bl_led_get_gpio(led), "Invalid pin value in led %i\n", led); + break; + case 8: + __ASSERT((1U << 15) == bl_led_get_gpio(led), "Invalid pin value in led %i\n", led); + break; + case 9: + __ASSERT((1U << 6) == bl_led_get_gpio(led), "Invalid pin value in led %i\n", led); + break; + case 10: + __ASSERT((1U << 5) == bl_led_get_gpio(led), "Invalid pin value in led %i\n", led); + break; + case 11: + __ASSERT((1U << 0) == bl_led_get_gpio(led), "Invalid pin value in led %i\n", led); + break; + case 12: + __ASSERT((1U << 4) == bl_led_get_gpio(led), "Invalid pin value in led %i\n", led); + break; + case 13: + __ASSERT((1U << 15) == bl_led_get_gpio(led), "Invalid pin value in led %i\n", led); + break; + case 14: + __ASSERT((1U << 1) == bl_led_get_gpio(led), "Invalid pin value in led %i\n", led); + break; + case 15: + __ASSERT((1U << 2) == bl_led_get_gpio(led), "Invalid pin value in led %i\n", led); + break; + #endif + } + } + printf("\nSuccess testing bl_led_get_gpio\n"); + + printf("\nTesting bl_led_status_set(), please check for a red led blinking\n"); + for (int i = 0 ; i < LOOPS ; i++){ + bl_led_status_set(true); + k_msleep(SLEEP_TIME_MS); + bl_led_status_set(false); + k_msleep(SLEEP_TIME_MS); + } + + bl_led_init(); + + printf("\nTesting bl_led_set(), please check for all leds blinking\n"); + for (int i = 0 ; i < LOOPS ; i++){ + bl_led_set(0xffff); + k_msleep(SLEEP_TIME_MS); + bl_led_set(0); + k_msleep(SLEEP_TIME_MS); + } +}; \ No newline at end of file diff --git a/tests/led/prj.conf b/tests/led/prj.conf new file mode 100644 index 0000000..573117c --- /dev/null +++ b/tests/led/prj.conf @@ -0,0 +1 @@ +CONFIG_ASSERT=y \ No newline at end of file diff --git a/tests/led/main.c b/tests/led/zephyr_based.c similarity index 100% rename from tests/led/main.c rename to tests/led/zephyr_based.c