1
0
mirror of https://github.com/RIOT-OS/RIOT.git synced 2024-12-29 04:50:03 +01:00

pkg/ucglib: refactor the Ucglib package

- Passing RIOT-OS specific data as user_ptr
- Added necessary macros to Makefile.dep
- Added missing explicit dependency to xtimer module
- Added ucg_riotos.h with the RIOT-OS specific functionality
- Removed the now-obsolete patch of Ucglib
- Other minor fixes
This commit is contained in:
Bas Stottelaar 2020-01-12 18:24:06 +01:00
parent 3d4a330153
commit 7d73e8acaf
7 changed files with 133 additions and 57 deletions

View File

@ -1,6 +1,6 @@
PKG_NAME=ucglib
PKG_URL=https://github.com/olikraus/ucglib
PKG_VERSION=bf48515702dd7c87cbacdd17989738f33f003df2
PKG_VERSION=230f15e3bcd3c84977780e84bd855ac89c1959ee
PKG_LICENSE=BSD-2-Clause
include $(RIOTBASE)/pkg/pkg.mk

View File

@ -1,2 +1,6 @@
USEMODULE += xtimer
FEATURES_REQUIRED += periph_gpio
USEMODULE += ucglib_riot
USEMODULE += ucglib_csrc

View File

@ -1,4 +1,8 @@
INCLUDES += -I$(PKGDIRBASE)/ucglib/csrc
INCLUDES += -I$(RIOTBASE)/pkg/ucglib/contrib
# The RIOT-OS interface needs this to store peripheral information.
CFLAGS += -DWITH_USER_PTR
# Link SDL if enabled.
ifneq (,$(filter ucglib_sdl,$(USEMODULE)))

View File

@ -13,44 +13,36 @@ This package patches the original source to add an interface for RIOT-OS.
Only the callback for SPI peripherals is supported:
* `ucg_com_riotos_hw_spi`
* `ucg_com_hw_spi_riotos`
Ucglib needs to map pin numbers to RIOT-OS pin numbers. It also needs to know which peripheral to use. The following two methods can be used to set this information.
These methods require a structure containing peripheral information (`ucg_riotos_t`), that is set using the `ucg_SetUserPtr` function. This structure contains the peripheral and pin mapping.
* `ucg_SetPins(ucg_dev, pins, bitmap)`
* `ucg_SetDevice(ucg_dev, dev)`
Note: `pins` should point to `gpio_t` array of Ucglib pin numbers to RIOT-OS pins. Due to this, `pins` can take up an additional 100 bytes, because it will use memory for the pins you do not map. You can overcome this limitation by implementing `ucg_com_riotos_hw_spi` yourself and hardcode the pins.
If the above interface is not sufficient, it is still possible to write a dedicated interface by (re-)implementing the methods above. Refer to the [Ucglib wiki](https://github.com/olikraus/ucglib/wiki) for more information.
### Example
```
```c
ucg_t ucg;
gpio_t pins[] = {
[UCG_PIN_CS] = GPIO(PA, 0),
[UCG_PIN_CD] = GPIO(PA, 1),
[UCG_PIN_RESET] = GPIO(PA, 2)
ucg_riotos_t user_data =
{
.device_index = SPI_DEV(0),
.pin_cs = GPIO_PIN(PA, 0),
.pin_cd = GPIO_PIN(PA, 1),
.pin_reset = GPIO_PIN(PA, 2)
};
uint32_t bitmap = (
(1 << UCG_PIN_CS) +
(1 << UCG_PIN_CD) +
(1 << UCG_PIN_RESET)
);
ucg_SetUserPtr(&ucg, &user_data);
ucg_SetPins(&ucg, pins, bitmap);
ucg_SetDevice(&ucg, SPI_DEV(0));
ucg_Init(&ucg, ucg_dev_ssd1331_18x96x64_univision, ucg_ext_ssd1331_18, ucg_com_riotos_hw_spi);
ucg_Init(&ucg, ucg_dev_ssd1331_18x96x64_univision, ucg_ext_ssd1331_18, ucg_com_hw_spi_riotos);
```
## Virtual displays
For targets without an I2C or SPI, a virtual display is available. Support for a virtual display is not compiled in by default.
For targets without SPI, a virtual display is available. Support for a virtual display is not compiled by default.
* By adding `USEMODULE += ucglib_sdl`, a SDL virtual display will be used. This is only available on native targets that have SDL2 installed. It uses `sdl2-config` to find the headers and libraries. Note that RIOT-OS builds 32-bit binaries and requires 32-bit SDL2 libraries.
### Example
```
```c
ucg_t ucg;
ucg_Init(&ucg, ucg_sdl_dev_cb, ucg_ext_none, NULL);

View File

@ -18,17 +18,18 @@
* @}
*/
#include "ucg.h"
#include <stdio.h>
#include "ucg_riotos.h"
#include "xtimer.h"
#ifdef MODULE_PERIPH_SPI
#include "periph/spi.h"
#include "periph/i2c.h"
#endif
#include "periph/gpio.h"
#include <stdio.h>
#ifdef SPI_NUMOF
#ifdef MODULE_PERIPH_SPI
static spi_clk_t ucg_serial_clk_speed_to_spi_speed(uint32_t serial_clk_speed)
{
if (serial_clk_speed < 100) {
@ -46,37 +47,47 @@ static spi_clk_t ucg_serial_clk_speed_to_spi_speed(uint32_t serial_clk_speed)
return SPI_CLK_100KHZ;
}
#endif /* SPI_NUMOF */
#endif /* MODULE_PERIPH_SPI */
static void ucg_enable_pins(gpio_t *pins, uint32_t pins_enabled)
/**
* @brief Enable the selected pins in RIOT-OS.
*/
static void _enable_pins(const ucg_riotos_t *ucg_riot_ptr)
{
uint8_t i;
/* no hardware peripheral is being used, nothing to be done */
if (ucg_riot_ptr == NULL) {
return;
}
for (i = 0; i < 32; i++) {
if (pins_enabled & ((uint32_t)1 << i)) {
if (pins[i] != GPIO_UNDEF) {
if (i < UCG_PIN_COUNT) {
gpio_init(pins[i], GPIO_OUT);
}
else {
gpio_init(pins[i], GPIO_IN);
}
}
}
if (ucg_riot_ptr->pin_cs != GPIO_UNDEF) {
gpio_init(ucg_riot_ptr->pin_cs, GPIO_OUT);
}
if (ucg_riot_ptr->pin_cd != GPIO_UNDEF) {
gpio_init(ucg_riot_ptr->pin_cd, GPIO_OUT);
}
if (ucg_riot_ptr->pin_reset != GPIO_UNDEF) {
gpio_init(ucg_riot_ptr->pin_reset, GPIO_OUT);
}
}
#ifdef SPI_NUMOF
int16_t ucg_com_riotos_hw_spi(ucg_t *ucg, int16_t msg, uint16_t arg, uint8_t *data)
#ifdef MODULE_PERIPH_SPI
int16_t ucg_com_hw_spi_riotos(ucg_t *ucg, int16_t msg, uint16_t arg, uint8_t *data)
{
spi_t dev = (spi_t) ucg->dev;
const ucg_riotos_t *ucg_riot_ptr = ucg_GetUserPtr(ucg);
/* assert that user_ptr is correctly set */
assert(ucg_riot_ptr != NULL);
spi_t dev = SPI_DEV(ucg_riot_ptr->device_index);
switch (msg) {
case UCG_COM_MSG_POWER_UP:
/* setup pins */
ucg_enable_pins(ucg->pin_list, ucg->pins_enabled);
_enable_pins(ucg_riot_ptr);
/* setup Arduino SPI */
/* setup SPI */
spi_init_pins(dev);
spi_acquire(dev, GPIO_UNDEF, SPI_MODE_0,
ucg_serial_clk_speed_to_spi_speed(((ucg_com_info_t *)data)->serial_clk_speed));
@ -89,18 +100,18 @@ int16_t ucg_com_riotos_hw_spi(ucg_t *ucg, int16_t msg, uint16_t arg, uint8_t *da
xtimer_usleep(arg);
break;
case UCG_COM_MSG_CHANGE_RESET_LINE:
if (ucg->pins_enabled & (1 << UCG_PIN_RST)) {
gpio_write(ucg->pin_list[UCG_PIN_RST], arg);
if (ucg_riot_ptr != NULL && ucg_riot_ptr->pin_reset != GPIO_UNDEF) {
gpio_write(ucg_riot_ptr->pin_reset, arg);
}
break;
case UCG_COM_MSG_CHANGE_CS_LINE:
if (ucg->pins_enabled & (1 << UCG_PIN_CS)) {
gpio_write(ucg->pin_list[UCG_PIN_CS], arg);
if (ucg_riot_ptr != NULL && ucg_riot_ptr->pin_cs != GPIO_UNDEF) {
gpio_write(ucg_riot_ptr->pin_cs, arg);
}
break;
case UCG_COM_MSG_CHANGE_CD_LINE:
if (ucg->pins_enabled & (1 << UCG_PIN_CD)) {
gpio_write(ucg->pin_list[UCG_PIN_CD], arg);
if (ucg_riot_ptr != NULL && ucg_riot_ptr->pin_cd != GPIO_UNDEF) {
gpio_write(ucg_riot_ptr->pin_cd, arg);
}
break;
case UCG_COM_MSG_SEND_BYTE:
@ -127,8 +138,8 @@ int16_t ucg_com_riotos_hw_spi(ucg_t *ucg, int16_t msg, uint16_t arg, uint8_t *da
case UCG_COM_MSG_SEND_CD_DATA_SEQUENCE:
while (arg--) {
if (*data != 0) {
if (ucg->pins_enabled & (1 << UCG_PIN_CD)) {
gpio_write(ucg->pin_list[UCG_PIN_CD], *data);
if (ucg_riot_ptr != NULL && ucg_riot_ptr->pin_cd != GPIO_UNDEF) {
gpio_write(ucg_riot_ptr->pin_cd, *data);
}
}
@ -141,9 +152,9 @@ int16_t ucg_com_riotos_hw_spi(ucg_t *ucg, int16_t msg, uint16_t arg, uint8_t *da
return 1;
}
#endif /* SPI_NUMOF */
#endif /* MODULE_PERIPH_SPI */
ucg_int_t ucg_dev_dummy_cb(ucg_t *ucg, ucg_int_t msg, void *data)
ucg_int_t ucg_dev_dummy_riotos(ucg_t *ucg, ucg_int_t msg, void *data)
{
static uint32_t pixels;

View File

@ -0,0 +1,65 @@
/*
* Copyright (C) 2020 Bas Stottelaar <basstottelaar@gmail.com>
*
* This file is subject to the terms and conditions of the GNU Lesser
* General Public License v2.1. See the file LICENSE in the top level
* directory for more details.
*/
/**
* @ingroup pkg_ucglib
* @{
*
* @file
* @brief Ucglib driver for interacting with RIOT-OS peripherals
*
* @author Bas Stottelaar <basstottelaar@gmail.com>
*
* @}
*/
#ifndef UCG_RIOTOS_H
#define UCG_RIOTOS_H
#include "ucg.h"
#include "periph/gpio.h"
#ifdef __cplusplus
extern "C" {
#endif
/**
* @brief Holds RIOT-OS specific peripheral data.
*
* This structure has to be set via the Ucglib function @p ucg_SetUserPtr,
* prior to the call to @p ucg_Init.
*
* The structure can be easily extended with further required definitions (e.g
* other pins) if necessary, without breaking the RIOT-OS adaptation of Ucglib.
*/
typedef struct {
void *user_ptr; /**< Pointer to optionally store any additional user-data */
unsigned int device_index; /**< Index of the SPI device */
gpio_t pin_cs; /**< Pin for SPI CS, GPIO_UNDEF if not used */
gpio_t pin_cd; /**< Pin for SPI CD, GPIO_UNDEF if not used */
gpio_t pin_reset; /**< Pin for RESET, GPIO_UNDEF if not used */
} ucg_riotos_t;
/**
* To be used as the u8x8_msg_cb as gpio_and_delay_cb in u8x8_Setup() for use with RIOT-OS
*/
int16_t ucg_com_hw_spi_riotos(ucg_t *ucg, int16_t msg, uint16_t arg, uint8_t *data);
/**
* To be used as the u8x8_msg_cb as gpio_and_delay_cb in u8x8_Setup() for use with RIOT-OS.
*/
ucg_int_t ucg_dev_dummy_riotos(ucg_t *ucg, ucg_int_t msg, void *data);
#ifdef __cplusplus
}
#endif
#endif /* UCG_RIOTOS_H */