mirror of
https://github.com/RIOT-OS/RIOT.git
synced 2024-12-29 04:50:03 +01:00
d63d58ac0b
The expandable GPIO API requires the comparison of structured GPIO types. This means that inline functions must be used instead of direct comparisons. For the migration process, packages must first be changed so that they use the inline comparison functions.
185 lines
5.1 KiB
C
185 lines
5.1 KiB
C
/*
|
|
* Copyright (C) 2018 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 to interact with RIOT-OS drivers.
|
|
*
|
|
* @author Bas Stottelaar <basstottelaar@gmail.com>
|
|
*
|
|
* @}
|
|
*/
|
|
|
|
#include <stdio.h>
|
|
|
|
#include "ucg_riotos.h"
|
|
|
|
#include "xtimer.h"
|
|
|
|
#ifdef MODULE_PERIPH_SPI
|
|
#include "periph/spi.h"
|
|
#endif
|
|
#include "periph/gpio.h"
|
|
|
|
#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) {
|
|
return SPI_CLK_10MHZ;
|
|
}
|
|
else if (serial_clk_speed < 200) {
|
|
return SPI_CLK_5MHZ;
|
|
}
|
|
else if (serial_clk_speed < 1000) {
|
|
return SPI_CLK_1MHZ;
|
|
}
|
|
else if (serial_clk_speed < 2500) {
|
|
return SPI_CLK_400KHZ;
|
|
}
|
|
|
|
return SPI_CLK_100KHZ;
|
|
}
|
|
#endif /* MODULE_PERIPH_SPI */
|
|
|
|
/**
|
|
* @brief Enable the selected pins in RIOT-OS.
|
|
*/
|
|
static void _enable_pins(const ucg_riotos_t *ucg_riot_ptr)
|
|
{
|
|
/* no hardware peripheral is being used, nothing to be done */
|
|
if (ucg_riot_ptr == NULL) {
|
|
return;
|
|
}
|
|
|
|
if (gpio_is_valid(ucg_riot_ptr->pin_cs)) {
|
|
gpio_init(ucg_riot_ptr->pin_cs, GPIO_OUT);
|
|
}
|
|
|
|
if (gpio_is_valid(ucg_riot_ptr->pin_cd)) {
|
|
gpio_init(ucg_riot_ptr->pin_cd, GPIO_OUT);
|
|
}
|
|
|
|
if (gpio_is_valid(ucg_riot_ptr->pin_reset)) {
|
|
gpio_init(ucg_riot_ptr->pin_reset, GPIO_OUT);
|
|
}
|
|
}
|
|
|
|
#ifdef MODULE_PERIPH_SPI
|
|
int16_t ucg_com_hw_spi_riotos(ucg_t *ucg, int16_t msg, uint16_t arg, uint8_t *data)
|
|
{
|
|
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 */
|
|
_enable_pins(ucg_riot_ptr);
|
|
|
|
/* 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));
|
|
|
|
break;
|
|
case UCG_COM_MSG_POWER_DOWN:
|
|
spi_release(dev);
|
|
break;
|
|
case UCG_COM_MSG_DELAY:
|
|
xtimer_usleep(arg);
|
|
break;
|
|
case UCG_COM_MSG_CHANGE_RESET_LINE:
|
|
if (ucg_riot_ptr != NULL && gpio_is_valid(ucg_riot_ptr->pin_reset)) {
|
|
gpio_write(ucg_riot_ptr->pin_reset, arg);
|
|
}
|
|
break;
|
|
case UCG_COM_MSG_CHANGE_CS_LINE:
|
|
if (ucg_riot_ptr != NULL && gpio_is_valid(ucg_riot_ptr->pin_cs)) {
|
|
gpio_write(ucg_riot_ptr->pin_cs, arg);
|
|
}
|
|
break;
|
|
case UCG_COM_MSG_CHANGE_CD_LINE:
|
|
if (ucg_riot_ptr != NULL && gpio_is_valid(ucg_riot_ptr->pin_cd)) {
|
|
gpio_write(ucg_riot_ptr->pin_cd, arg);
|
|
}
|
|
break;
|
|
case UCG_COM_MSG_SEND_BYTE:
|
|
spi_transfer_byte(dev, GPIO_UNDEF, true, (uint8_t) arg);
|
|
break;
|
|
case UCG_COM_MSG_REPEAT_1_BYTE:
|
|
while (arg--) {
|
|
spi_transfer_byte(dev, GPIO_UNDEF, true, ((uint8_t *) data)[0]);
|
|
}
|
|
break;
|
|
case UCG_COM_MSG_REPEAT_2_BYTES:
|
|
while (arg--) {
|
|
spi_transfer_bytes(dev, GPIO_UNDEF, true, data, NULL, 2);
|
|
}
|
|
break;
|
|
case UCG_COM_MSG_REPEAT_3_BYTES:
|
|
while (arg--) {
|
|
spi_transfer_bytes(dev, GPIO_UNDEF, true, data, NULL, 3);
|
|
}
|
|
break;
|
|
case UCG_COM_MSG_SEND_STR:
|
|
spi_transfer_bytes(dev, GPIO_UNDEF, true, data, NULL, arg);
|
|
break;
|
|
case UCG_COM_MSG_SEND_CD_DATA_SEQUENCE:
|
|
while (arg--) {
|
|
if (*data != 0) {
|
|
if (ucg_riot_ptr != NULL && ucg_riot_ptr->pin_cd != GPIO_UNDEF) {
|
|
gpio_write(ucg_riot_ptr->pin_cd, *data);
|
|
}
|
|
}
|
|
|
|
data++;
|
|
spi_transfer_bytes(dev, GPIO_UNDEF, true, data, NULL, 1);
|
|
data++;
|
|
}
|
|
break;
|
|
}
|
|
|
|
return 1;
|
|
}
|
|
#endif /* MODULE_PERIPH_SPI */
|
|
|
|
ucg_int_t ucg_dev_dummy_riotos(ucg_t *ucg, ucg_int_t msg, void *data)
|
|
{
|
|
static uint32_t pixels;
|
|
|
|
switch (msg) {
|
|
case UCG_MSG_DEV_POWER_UP:
|
|
puts("ucg: UCG_MSG_DEV_POWER_UP");
|
|
return 1;
|
|
case UCG_MSG_DEV_POWER_DOWN:
|
|
puts("ucg: UCG_MSG_DEV_POWER_DOWN");
|
|
return 1;
|
|
case UCG_MSG_GET_DIMENSION:
|
|
puts("ucg: UCG_MSG_GET_DIMENSION");
|
|
((ucg_wh_t *)data)->w = 128;
|
|
((ucg_wh_t *)data)->h = 128;
|
|
return 1;
|
|
case UCG_MSG_DRAW_PIXEL:
|
|
pixels++;
|
|
|
|
/* log each 128th draw */
|
|
if (pixels % 128 == 0) {
|
|
printf("ucg: UCG_MSG_DRAW_PIXEL (%" PRIu32 ")\n", pixels);
|
|
}
|
|
|
|
return 1;
|
|
}
|
|
return ucg_dev_default_cb(ucg, msg, data);
|
|
}
|