Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Replace libopen's GPIO APIS by Zephyr GPIO APIs #3

Merged
merged 13 commits into from
Jul 7, 2021
5 changes: 5 additions & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -33,3 +33,8 @@ target_sources(app PRIVATE
# src/acq/source.c
# src/acq/timer.c
)

add_compile_definitions(
BL_REVISION=2
REVISION=2
)
8 changes: 7 additions & 1 deletion boards/arm/bloodlight_rev2/Kconfig.defconfig
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -25,4 +30,5 @@ config USB_DEVICE_PID
default 0x5740
depends on USB
help
USB device product ID. MUST be configured by vendor.
USB device product ID. MUST be configured by vendor.

161 changes: 121 additions & 40 deletions src/led.c
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,8 @@
#include <stddef.h>
#include <stdint.h>

// #include <libopencm3/stm32/rcc.h>
// #include <libopencm3/stm32/gpio.h>
#include <drivers/clock_control.h>
#include <drivers/gpio.h>

#include "common/error.h"
#include "common/util.h"
Expand Down Expand Up @@ -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,
Expand Down Expand Up @@ -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);
}
Expand All @@ -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 */
Expand All @@ -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);
Expand All @@ -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);

Expand Down Expand Up @@ -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);
Expand All @@ -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);
}*/
Expand All @@ -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];
}
Expand Down
16 changes: 15 additions & 1 deletion src/led.h
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,8 @@
#include "common/error.h"
#include "common/led.h"

#include <drivers/gpio.h>

/** LED source globals */
typedef struct {
uint8_t led;
Expand All @@ -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;
Expand Down Expand Up @@ -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
Expand All @@ -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
8 changes: 6 additions & 2 deletions src/spi.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -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;
Expand Down
7 changes: 6 additions & 1 deletion tests/led/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,11 @@ zephyr_include_directories(${CMAKE_SOURCE_DIR}/../..)
project(led_test)

target_sources(app PRIVATE
main.c
bloodlight_based.c
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It isn't clear why you have renamed 'main.c' as 'bloodlight_based.c'. The intended meaning of the name 'bloodlight based' isn't very clear.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I edited the commit description. See: 8afe0b7

../../src/led.c
)

add_compile_definitions(
BL_REVISION=2
REVISION=2
)
Loading