Browse Source

drivers/dsp0401: initial implementation

master
Alexandre Abadie 6 years ago
parent
commit
a4e16cd7e9
  1. 6
      drivers/Makefile.dep
  2. 3
      drivers/Makefile.include
  3. 1
      drivers/dsp0401/Makefile
  4. 249
      drivers/dsp0401/dsp0401.c
  5. 81
      drivers/dsp0401/include/dsp0401_params.h
  6. 109
      drivers/include/dsp0401.h

6
drivers/Makefile.dep

@ -83,6 +83,12 @@ ifneq (,$(filter dht,$(USEMODULE)))
FEATURES_REQUIRED += periph_gpio
endif
ifneq (,$(filter dsp0401,$(USEMODULE)))
USEMODULE += xtimer
FEATURES_REQUIRED += periph_gpio
FEATURES_REQUIRED += periph_pwm
endif
ifneq (,$(filter enc28j60,$(USEMODULE)))
USEMODULE += netdev_eth
USEMODULE += xtimer

3
drivers/Makefile.include

@ -121,3 +121,6 @@ endif
ifneq (,$(filter lsm6dsl,$(USEMODULE)))
USEMODULE_INCLUDES += $(RIOTBASE)/drivers/lsm6dsl/include
endif
ifneq (,$(filter dsp0401,$(USEMODULE)))
USEMODULE_INCLUDES += $(RIOTBASE)/drivers/dsp0401/include
endif

1
drivers/dsp0401/Makefile

@ -0,0 +1 @@
include $(RIOTBASE)/Makefile.base

249
drivers/dsp0401/dsp0401.c

@ -0,0 +1,249 @@
/*
* Copyright (C) 2017 Inria
*
* 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 drivers_dsp0401
* @{
*
* @file
* @brief Device driver implementation for dsp0401 alphanumeric display
*
* @author Alexandre Abadie <alexandre.abadie@inria.fr>
*
* @}
*/
#include <inttypes.h>
#include <string.h>
#include "dsp0401.h"
#include "xtimer.h"
#include "periph/gpio.h"
#include "periph/pwm.h"
#define ENABLE_DEBUG (0)
#include "debug.h"
#define LATCH_DELAY (50U) /* 50 us */
#define SCK (dev->params.clk)
#define SDI (dev->params.sdi)
#define LAT (dev->params.lat)
#define PWM_PERIPH (dev->params.pwm)
#define PWM_CHAN (dev->params.pwm_channel)
#define BRIGHTNESS (dev->params.brightness)
#define PWM_FREQ (1000U)
#define PWM_STEPS (256U)
#define MOD_COUNT (dev->params.module_count)
/* Internal Ascii char map */
#define CHAR_MAP_MIN (30U)
#define CHAR_MAP_MAX (127U)
static const uint8_t dsp0401_charmap[][2] = {
/* dec: char */
{ 0x00, 0x00 }, /* 30: */
{ 0x00, 0x00 }, /* 31: */
{ 0x00, 0x00 }, /* 32: ' ' */
{ 0x00, 0x00 }, /* 33: ! */
{ 0x00, 0x00 }, /* 34: " */
{ 0x00, 0x00 }, /* 35: # */
{ 0xB5, 0xB5 }, /* 36: $ */
{ 0xB3, 0xB3 }, /* 37: % */
{ 0x00, 0x00 }, /* 38: & */
{ 0x01, 0x00 }, /* 39: ` */
{ 0x81, 0x00 }, /* 40: ( */
{ 0x00, 0x42 }, /* 41: ) */
{ 0x53, 0x53 }, /* 42: * */
{ 0x11, 0x11 }, /* 43: + */
{ 0x00, 0x00 }, /* 44: , */
{ 0x10, 0x10 }, /* 45: - */
{ 0x00, 0x04 }, /* 46: . */
{ 0x02, 0x02 }, /* 47: / */
{ 0xAC, 0xAC }, /* 48: 0 */
{ 0x01, 0x01 }, /* 49: 1 */
{ 0x9C, 0x9C }, /* 50: 2 */
{ 0xBC, 0x84 }, /* 51: 3 */
{ 0x38, 0x30 }, /* 52: 4 */
{ 0xB4, 0xB4 }, /* 53: 5 */
{ 0xB4, 0xBC }, /* 54: 6 */
{ 0x16, 0x92 }, /* 55: 7 */
{ 0xBC, 0xBC }, /* 56: 8 */
{ 0xBC, 0xB4 }, /* 57: 9 */
{ 0x04, 0x04 }, /* 58: : */
{ 0x04, 0x02 }, /* 59: ; */
{ 0x00, 0x00 }, /* 60: < */
{ 0x90, 0x14 }, /* 61: = */
{ 0x00, 0x00 }, /* 62: > */
{ 0x00, 0x00 }, /* 63: ? */
{ 0xAC, 0x9D }, /* 64: @ */
{ 0x3C, 0xB8 }, /* 65: A */
{ 0xB1, 0xBC }, /* 66: B */
{ 0x84, 0xAC }, /* 67: C */
{ 0xAD, 0x85 }, /* 68: D */
{ 0x84, 0xBC }, /* 69: E */
{ 0x04, 0xB8 }, /* 70: F */
{ 0xB4, 0xAC }, /* 71: G */
{ 0x38, 0x38 }, /* 72: H */
{ 0x85, 0x85 }, /* 73: I */
{ 0xA8, 0x0C }, /* 74: J */
{ 0x42, 0x38 }, /* 75: K */
{ 0x80, 0x2C }, /* 76: L */
{ 0x2A, 0x68 }, /* 77: M */
{ 0x68, 0x68 }, /* 78: N */
{ 0xAC, 0xAC }, /* 79: 0 */
{ 0x1C, 0xB8 }, /* 80: P */
{ 0xEC, 0xAC }, /* 81: Q */
{ 0x5C, 0xB8 }, /* 82: R */
{ 0xB4, 0xB4 }, /* 83: S */
{ 0x05, 0x81 }, /* 84: T */
{ 0xA8, 0x2C }, /* 85: U */
{ 0x02, 0x2A }, /* 86: V */
{ 0x68, 0x2A }, /* 87: W */
{ 0x42, 0x42 }, /* 88: X */
{ 0x02, 0x42 }, /* 89: Y */
{ 0x86, 0x86 }, /* 90: Z */
{ 0x00, 0xAC }, /* 91: [ */
{ 0x40, 0x40 }, /* 92: \ */
{ 0xAC, 0x00 }, /* 93: ] */
{ 0x00, 0x00 }, /* 94: ^ */
{ 0x80, 0x04 }, /* 95: _ */
{ 0x00, 0x40 }, /* 96: ` */
{ 0x00, 0x00 }, /* 97: a */
{ 0x00, 0x00 }, /* 98: b */
{ 0x00, 0x00 }, /* 99: c */
{ 0x00, 0x00 }, /* 100: d */
{ 0x00, 0x00 }, /* 101: e */
{ 0x00, 0x00 }, /* 102: f */
{ 0x00, 0x00 }, /* 103: g */
{ 0x00, 0x00 }, /* 104: h */
{ 0x00, 0x00 }, /* 105: i */
{ 0x00, 0x00 }, /* 106: j */
{ 0x00, 0x00 }, /* 107: k */
{ 0x00, 0x00 }, /* 108: l */
{ 0x00, 0x00 }, /* 109: m */
{ 0x00, 0x00 }, /* 110: n */
{ 0x00, 0x00 }, /* 111: o */
{ 0x00, 0x00 }, /* 112: p */
{ 0x00, 0x00 }, /* 113: q */
{ 0x00, 0x00 }, /* 114: r */
{ 0x00, 0x00 }, /* 115: s */
{ 0x00, 0x00 }, /* 116: t */
{ 0x00, 0x00 }, /* 117: u */
{ 0x00, 0x00 }, /* 118: v */
{ 0x00, 0x00 }, /* 119: w */
{ 0x00, 0x00 }, /* 120: x */
{ 0x00, 0x00 }, /* 121: y */
{ 0x00, 0x00 }, /* 122: z */
{ 0x85, 0x11 }, /* 123: { */
{ 0x01, 0x01 }, /* 124: | */
{ 0x11, 0x85 }, /* 125: } */
{ 0x00, 0x00 }, /* 126: ~ */
{ 0x00, 0x00 }, /* 127: */
};
static void _shift_char(dsp0401_t *dev, uint8_t c)
{
/* Unsupported chars not displayed */
if ((c < CHAR_MAP_MIN) || (c > CHAR_MAP_MAX)) {
c = ' ';
}
for (unsigned p = 0 ; p < 2 ; ++p) {
for (unsigned i = 0; i < 8; ++i) {
gpio_write(SDI, !!(dsp0401_charmap[c - CHAR_MAP_MIN][p] & (1 << (7 - i))));
gpio_set(SCK);
gpio_clear(SCK);
}
}
}
static void _latch(dsp0401_t *dev)
{
xtimer_usleep(LATCH_DELAY);
gpio_set(LAT);
xtimer_usleep(LATCH_DELAY);
gpio_clear(LAT);
xtimer_usleep(LATCH_DELAY);
}
int dsp0401_init(dsp0401_t *dev, const dsp0401_params_t *params)
{
dev->params = *params;
/* Initialize clock pin and set it to low */
if (gpio_init(SCK, GPIO_OUT) < 0) {
DEBUG("[ERROR] CLK GPIO initialization failed.");
return -DSP0401_ERR_CLK_GPIO;
}
gpio_clear(SCK);
/* Initialize data pin */
if (gpio_init(SDI, GPIO_OUT) < 0) {
DEBUG("[ERROR] SDI GPIO initialization failed.");
return -DSP0401_ERR_SDI_GPIO;
}
gpio_clear(SDI);
/* Initialize latch pin and set it to low */
if (gpio_init(LAT, GPIO_OUT) < 0) {
DEBUG("[ERROR] LAT GPIO initialization failed.");
return -DSP0401_ERR_LAT_GPIO;
}
gpio_clear(LAT);
/* Initialize PWM used for LED brightness */
if (!pwm_init(PWM_PERIPH, PWM_LEFT, PWM_FREQ, PWM_STEPS)) {
DEBUG("[ERROR] PWM initialization failed.");
return -DSP0401_ERR_PWM;
}
pwm_set(PWM_PERIPH, PWM_CHAN, BRIGHTNESS);
dsp0401_clear_text(dev);
return DSP0401_OK;
}
void dsp0401_display_text(dsp0401_t *dev, char *text)
{
unsigned text_len = strlen(text);
for (unsigned i = 0 ; i < MOD_COUNT * 4; ++i) {
if (i < text_len) {
_shift_char(dev, text[i]);
} else {
_shift_char(dev, ' ');
}
}
_latch(dev);
}
void dsp0401_clear_text(dsp0401_t *dev)
{
/* each module has 4 alphanumeric displays */
for (unsigned i = 0; i < MOD_COUNT * 4; ++i) {
_shift_char(dev, ' ');
}
_latch(dev);
}
void dsp0401_scroll_text(dsp0401_t *dev, char *text, uint16_t delay)
{
dsp0401_clear_text(dev);
for (unsigned i = 0; i < strlen(text); ++i) {
_shift_char(dev, text[i]);
_latch(dev);
xtimer_usleep((uint32_t)(delay * US_PER_MS));
}
for (unsigned i = 0; i < MOD_COUNT * 4; ++i) {
_shift_char(dev, ' ');
_latch(dev);
xtimer_usleep((uint32_t)(delay * US_PER_MS));
}
}

81
drivers/dsp0401/include/dsp0401_params.h

@ -0,0 +1,81 @@
/*
* Copyright (C) 2017 Inria
*
* 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 drivers_dsp0401
*
* @{
* @file
* @brief Default configuration for DSP0401
*
* @author Alexandre Abadie <alexandre.abadie@inria.fr>
*/
#ifndef DSP0401_PARAMS_H
#define DSP0401_PARAMS_H
#include "board.h"
#include "dsp0401.h"
#include "periph/gpio.h"
#include "periph/pwm.h"
#ifdef __cplusplus
extern "C" {
#endif
/**
* @brief Set default configuration parameters for the DSP0401 (for Nucleo-F411)
* @{
*/
#ifndef DSP0401_PARAM_SDI_PIN
#define DSP0401_PARAM_SDI_PIN GPIO_PIN(0, 10) /* D2 */
#endif
#ifndef DSP0401_PARAM_CLK_PIN
#define DSP0401_PARAM_CLK_PIN GPIO_PIN(1, 3) /* D3 */
#endif
#ifndef DSP0401_PARAM_LAT_PIN
#define DSP0401_PARAM_LAT_PIN GPIO_PIN(1, 5) /* D4 */
#endif
#ifndef DSP0401_PARAM_PWM_DEV
#define DSP0401_PARAM_PWM_DEV PWM_DEV(1)
#endif
#ifndef DSP0401_PARAM_PWM_CHAN
#define DSP0401_PARAM_PWM_CHAN (0U)
#endif
#ifndef DSP0401_PARAM_BRIGHTNESS
#define DSP0401_PARAM_BRIGHTNESS (255U)
#endif
#ifndef DSP0401_PARAM_MODULE_COUNT
#define DSP0401_PARAM_MODULE_COUNT (1U)
#endif
#define DSP0401_PARAMS_DEFAULT { \
.sdi = DSP0401_PARAM_SDI_PIN, \
.clk = DSP0401_PARAM_CLK_PIN, \
.lat = DSP0401_PARAM_LAT_PIN, \
.pwm = DSP0401_PARAM_PWM_DEV, \
.pwm_channel = DSP0401_PARAM_PWM_CHAN, \
.brightness = DSP0401_PARAM_BRIGHTNESS, \
.module_count = DSP0401_PARAM_MODULE_COUNT }
/**@}*/
/**
* @brief Configure DSP0401
*/
static const dsp0401_params_t dsp0401_params[] =
{
DSP0401_PARAMS_DEFAULT,
};
#ifdef __cplusplus
}
#endif
#endif /* DSP0401_PARAMS_H */
/** @} */

109
drivers/include/dsp0401.h

@ -0,0 +1,109 @@
/*
* Copyright (C) 2017 Inria
*
* 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.
*/
/**
* @defgroup drivers_dsp0401 DSP0401
* @ingroup drivers_actuators
* @brief Device driver interface for the DSP0401 alphanumeric display
* @{
*
* @file
* @brief Device driver interface for the DSP0401 alphanumeric display
*
* @author Alexandre Abadie <alexandre.abadie@inria.fr>
*/
#ifndef DSP0401_H
#define DSP0401_H
#include <inttypes.h>
#include <stdint.h>
#include "periph/gpio.h"
#include "periph/pwm.h"
#ifdef __cplusplus
extern "C" {
#endif
/**
* @name Return codes
* @{
*/
enum {
DSP0401_OK = 0, /**< All ok */
DSP0401_ERR_CLK_GPIO, /**< Something went wrong with CLK GPIO */
DSP0401_ERR_SDI_GPIO, /**< Something went wrong with SDI GPIO */
DSP0401_ERR_LAT_GPIO, /**< Something went wrong with LAT GPIO */
DSP0401_ERR_PWM, /**< Something went wrong with PWM */
};
/** @} */
/**
* @brief Device initialization parameters
*/
typedef struct {
gpio_t sdi; /**< Data input pin */
gpio_t clk; /**< Clock pin */
gpio_t lat; /**< Latch pin */
pwm_t pwm; /**< PWM device */
uint8_t pwm_channel; /**< PWM device channel */
uint8_t brightness; /**< LED brightness */
uint8_t module_count; /**< Number of connected modules */
} dsp0401_params_t;
/**
* @brief Device descriptor for the DSP0401
*/
typedef struct {
dsp0401_params_t params; /**< Device parameters */
} dsp0401_t;
/**
* @brief Initialize the given DSP0401
*
* @param[out] dev Initialized device descriptor of DSP0401 device
* @param[in] params Device parameters to use
*
* @return DSP0401_OK if everything is good
* @return -DSP0401_ERR_CLK_GPIO if an error occured during CLK GPIO initialization
* @return -DSP0401_ERR_SDI_GPIO if an error occured during SDI GPIO initialization
* @return -DSP0401_ERR_LAT_GPIO if an error occured during LAT GPIO initialization
* @return -DSP0401_ERR_PWM if an error occured during PWM initialization
*/
int dsp0401_init(dsp0401_t *dev, const dsp0401_params_t *params);
/**
* @brief Display the given text on the DSP0401
*
* @param[in] dev Device descriptor of the DSP0401 device
* @param[in] text The text to display
*/
void dsp0401_display_text(dsp0401_t *dev, char *text);
/**
* @brief Clear the text displayed on the DSP0401
*
* @param[in] dev Device descriptor of the DSP0401 device
*/
void dsp0401_clear_text(dsp0401_t *dev);
/**
* @brief Scroll the given text on the DSP0401
*
* @param[in] dev Device descriptor of the DSP0401 device
* @param[in] text The text to scroll on the display
* @param[in] delay Delay in ms between each horizontal move
*/
void dsp0401_scroll_text(dsp0401_t *dev, char *text, uint16_t delay);
#ifdef __cplusplus
}
#endif
#endif /* DSP0401_H */
/** @} */
Loading…
Cancel
Save