Use c-periphery for GPIO
This commit is contained in:
parent
9cd635fe1c
commit
8d38070847
File diff suppressed because it is too large
Load Diff
|
@ -1,30 +1,121 @@
|
|||
#ifndef GPIO_H
|
||||
#define GPIO_H
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
// Direction
|
||||
#define GPIO_IN (0)
|
||||
#define GPIO_OUT (1)
|
||||
|
||||
// Value
|
||||
#define GPIO_LOW (0)
|
||||
#define GPIO_HIGH (1)
|
||||
|
||||
//nanopi
|
||||
#define GPIO_PIN(x) (x)
|
||||
|
||||
int exportGPIOPin(int pin);
|
||||
int unexportGPIOPin(int pin);
|
||||
|
||||
// GPIO_IN or GPIO_OUT
|
||||
int setGPIODirection(int pin, int direction);
|
||||
int getGPIODirection(int pin);
|
||||
|
||||
// GPIO_LOW or GPIO_HIGH
|
||||
int setGPIOValue(int pin, int value);
|
||||
int getGPIOValue(int pin);
|
||||
|
||||
#endif
|
||||
/*
|
||||
* c-periphery
|
||||
* https://github.com/vsergeev/c-periphery
|
||||
* License: MIT
|
||||
*/
|
||||
|
||||
#ifndef _PERIPHERY_GPIO_H
|
||||
#define _PERIPHERY_GPIO_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include <stddef.h>
|
||||
#include <stdbool.h>
|
||||
#include <stdint.h>
|
||||
|
||||
enum gpio_error_code {
|
||||
GPIO_ERROR_ARG = -1, /* Invalid arguments */
|
||||
GPIO_ERROR_OPEN = -2, /* Opening GPIO */
|
||||
GPIO_ERROR_NOT_FOUND = -3, /* Line name not found */
|
||||
GPIO_ERROR_QUERY = -4, /* Querying GPIO attributes */
|
||||
GPIO_ERROR_CONFIGURE = -5, /* Configuring GPIO attributes */
|
||||
GPIO_ERROR_UNSUPPORTED = -6, /* Unsupported attribute or operation */
|
||||
GPIO_ERROR_INVALID_OPERATION = -7, /* Invalid operation */
|
||||
GPIO_ERROR_IO = -8, /* Reading/writing GPIO */
|
||||
GPIO_ERROR_CLOSE = -9, /* Closing GPIO */
|
||||
};
|
||||
|
||||
typedef enum gpio_direction {
|
||||
GPIO_DIR_IN, /* Input */
|
||||
GPIO_DIR_OUT, /* Output, initialized to low */
|
||||
GPIO_DIR_OUT_LOW, /* Output, initialized to low */
|
||||
GPIO_DIR_OUT_HIGH, /* Output, initialized to high */
|
||||
} gpio_direction_t;
|
||||
|
||||
typedef enum gpio_edge {
|
||||
GPIO_EDGE_NONE, /* No interrupt edge */
|
||||
GPIO_EDGE_RISING, /* Rising edge 0 -> 1 */
|
||||
GPIO_EDGE_FALLING, /* Falling edge 1 -> 0 */
|
||||
GPIO_EDGE_BOTH /* Both edges X -> !X */
|
||||
} gpio_edge_t;
|
||||
|
||||
typedef enum gpio_bias {
|
||||
GPIO_BIAS_DEFAULT, /* Default line bias */
|
||||
GPIO_BIAS_PULL_UP, /* Pull-up */
|
||||
GPIO_BIAS_PULL_DOWN, /* Pull-down */
|
||||
GPIO_BIAS_DISABLE, /* Disable line bias */
|
||||
} gpio_bias_t;
|
||||
|
||||
typedef enum gpio_drive {
|
||||
GPIO_DRIVE_DEFAULT, /* Default line drive (push-pull) */
|
||||
GPIO_DRIVE_OPEN_DRAIN, /* Open drain */
|
||||
GPIO_DRIVE_OPEN_SOURCE, /* Open source */
|
||||
} gpio_drive_t;
|
||||
|
||||
/* Configuration structure for gpio_open_*advanced() functions */
|
||||
typedef struct gpio_config {
|
||||
gpio_direction_t direction;
|
||||
gpio_edge_t edge;
|
||||
gpio_bias_t bias;
|
||||
gpio_drive_t drive;
|
||||
bool inverted;
|
||||
const char *label; /* Can be NULL for default consumer label */
|
||||
} gpio_config_t;
|
||||
|
||||
typedef struct gpio_handle gpio_t;
|
||||
|
||||
/* Primary Functions */
|
||||
gpio_t *gpio_new(void);
|
||||
int gpio_open(gpio_t *gpio, const char *path, unsigned int line, gpio_direction_t direction);
|
||||
int gpio_open_name(gpio_t *gpio, const char *path, const char *name, gpio_direction_t direction);
|
||||
int gpio_open_advanced(gpio_t *gpio, const char *path, unsigned int line, const gpio_config_t *config);
|
||||
int gpio_open_name_advanced(gpio_t *gpio, const char *path, const char *name, const gpio_config_t *config);
|
||||
int gpio_open_sysfs(gpio_t *gpio, unsigned int line, gpio_direction_t direction);
|
||||
int gpio_read(gpio_t *gpio, bool *value);
|
||||
int gpio_write(gpio_t *gpio, bool value);
|
||||
int gpio_poll(gpio_t *gpio, int timeout_ms);
|
||||
int gpio_close(gpio_t *gpio);
|
||||
void gpio_free(gpio_t *gpio);
|
||||
|
||||
/* Read Event (for character device GPIOs) */
|
||||
int gpio_read_event(gpio_t *gpio, gpio_edge_t *edge, uint64_t *timestamp);
|
||||
|
||||
/* Poll Multiple */
|
||||
int gpio_poll_multiple(gpio_t **gpios, size_t count, int timeout_ms, bool *gpios_ready);
|
||||
|
||||
/* Getters */
|
||||
int gpio_get_direction(gpio_t *gpio, gpio_direction_t *direction);
|
||||
int gpio_get_edge(gpio_t *gpio, gpio_edge_t *edge);
|
||||
int gpio_get_bias(gpio_t *gpio, gpio_bias_t *bias);
|
||||
int gpio_get_drive(gpio_t *gpio, gpio_drive_t *drive);
|
||||
int gpio_get_inverted(gpio_t *gpio, bool *inverted);
|
||||
|
||||
/* Setters */
|
||||
int gpio_set_direction(gpio_t *gpio, gpio_direction_t direction);
|
||||
int gpio_set_edge(gpio_t *gpio, gpio_edge_t edge);
|
||||
int gpio_set_bias(gpio_t *gpio, gpio_bias_t bias);
|
||||
int gpio_set_drive(gpio_t *gpio, gpio_drive_t drive);
|
||||
int gpio_set_inverted(gpio_t *gpio, bool inverted);
|
||||
|
||||
/* Miscellaneous Properties */
|
||||
unsigned int gpio_line(gpio_t *gpio);
|
||||
int gpio_fd(gpio_t *gpio);
|
||||
int gpio_name(gpio_t *gpio, char *str, size_t len);
|
||||
int gpio_label(gpio_t *gpio, char *str, size_t len);
|
||||
int gpio_chip_fd(gpio_t *gpio);
|
||||
int gpio_chip_name(gpio_t *gpio, char *str, size_t len);
|
||||
int gpio_chip_label(gpio_t *gpio, char *str, size_t len);
|
||||
int gpio_tostring(gpio_t *gpio, char *str, size_t len);
|
||||
|
||||
/* Error Handling */
|
||||
int gpio_errno(gpio_t *gpio);
|
||||
const char *gpio_errmsg(gpio_t *gpio);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
|
|
|
@ -6,343 +6,319 @@ static const char i2c_bus[] = "/dev/i2c-1";
|
|||
static int spi_device;
|
||||
static const char spi_bus[] = "/dev/spidev0.0";
|
||||
|
||||
uint8_t u8x8_arm_linux_gpio_and_delay(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr)
|
||||
{
|
||||
(void) arg_ptr; /* suppress unused parameter warning */
|
||||
switch(msg)
|
||||
{
|
||||
case U8X8_MSG_DELAY_NANO: // delay arg_int * 1 nano second
|
||||
sleep_ns(arg_int);
|
||||
break;
|
||||
static const char gpio_device[] = "/dev/gpiochip0";
|
||||
|
||||
case U8X8_MSG_DELAY_100NANO: // delay arg_int * 100 nano seconds
|
||||
sleep_ns(arg_int * 100);
|
||||
break;
|
||||
// c-periphery GPIO pins
|
||||
gpio_t *pins[U8X8_PIN_CNT];
|
||||
|
||||
case U8X8_MSG_DELAY_10MICRO: // delay arg_int * 10 micro seconds
|
||||
sleep_us(arg_int * 10);
|
||||
break;
|
||||
void init_pin(u8x8_t *u8x8, int pin) {
|
||||
pins[pin] = gpio_new();
|
||||
if (gpio_open(pins[pin], gpio_device, u8x8->pins[pin], GPIO_DIR_OUT_HIGH)
|
||||
< 0) {
|
||||
fprintf(stderr, "gpio_open(): %s\n", gpio_errmsg(pins[pin]));
|
||||
}
|
||||
}
|
||||
|
||||
case U8X8_MSG_DELAY_MILLI: // delay arg_int * 1 milli second
|
||||
sleep_ms(arg_int);
|
||||
break;
|
||||
uint8_t u8x8_arm_linux_gpio_and_delay(u8x8_t *u8x8, uint8_t msg,
|
||||
uint8_t arg_int, void *arg_ptr) {
|
||||
(void) arg_ptr; /* suppress unused parameter warning */
|
||||
switch (msg) {
|
||||
case U8X8_MSG_DELAY_NANO: // delay arg_int * 1 nano second
|
||||
sleep_ns(arg_int);
|
||||
break;
|
||||
|
||||
case U8X8_MSG_DELAY_I2C:
|
||||
// arg_int is the I2C speed in 100KHz, e.g. 4 = 400 KHz
|
||||
// arg_int=1: delay by 5us, arg_int = 4: delay by 1.25us
|
||||
if(arg_int == 1)
|
||||
{
|
||||
sleep_us(5);
|
||||
}
|
||||
else if (arg_int == 4)
|
||||
{
|
||||
sleep_ns(1250);
|
||||
}
|
||||
break;
|
||||
case U8X8_MSG_DELAY_100NANO: // delay arg_int * 100 nano seconds
|
||||
sleep_ns(arg_int * 100);
|
||||
break;
|
||||
|
||||
case U8X8_MSG_GPIO_AND_DELAY_INIT:
|
||||
// Function which implements a delay, arg_int contains the amount of ms
|
||||
case U8X8_MSG_DELAY_10MICRO: // delay arg_int * 10 micro seconds
|
||||
sleep_us(arg_int * 10);
|
||||
break;
|
||||
|
||||
// printf("CLK:%d, DATA:%d, CS:%d, RST:%d, DC:%d\n", u8x8->pins[U8X8_PIN_SPI_CLOCK], u8x8->pins[U8X8_PIN_SPI_DATA], u8x8->pins[U8X8_PIN_CS], u8x8->pins[U8X8_PIN_RESET], u8x8->pins[U8X8_PIN_DC]);
|
||||
// printf("SDA:%d, SCL:%d\n", u8x8->pins[U8X8_PIN_I2C_DATA], u8x8->pins[U8X8_PIN_I2C_CLOCK]);
|
||||
|
||||
// SPI Pins
|
||||
if(u8x8->pins[U8X8_PIN_SPI_CLOCK] != U8X8_PIN_NONE)
|
||||
{
|
||||
exportGPIOPin(u8x8->pins[U8X8_PIN_SPI_CLOCK]);
|
||||
setGPIODirection(u8x8->pins[U8X8_PIN_SPI_CLOCK], GPIO_OUT);
|
||||
setGPIOValue(u8x8->pins[U8X8_PIN_SPI_CLOCK], GPIO_HIGH);
|
||||
}
|
||||
if(u8x8->pins[U8X8_PIN_SPI_DATA] != U8X8_PIN_NONE)
|
||||
{
|
||||
exportGPIOPin(u8x8->pins[U8X8_PIN_SPI_DATA]);
|
||||
setGPIODirection(u8x8->pins[U8X8_PIN_SPI_DATA], GPIO_OUT);
|
||||
setGPIOValue(u8x8->pins[U8X8_PIN_SPI_DATA], GPIO_HIGH);
|
||||
}
|
||||
if(u8x8->pins[U8X8_PIN_CS] != U8X8_PIN_NONE)
|
||||
{
|
||||
exportGPIOPin(u8x8->pins[U8X8_PIN_CS]);
|
||||
setGPIODirection(u8x8->pins[U8X8_PIN_CS], GPIO_OUT);
|
||||
setGPIOValue(u8x8->pins[U8X8_PIN_CS], GPIO_HIGH);
|
||||
}
|
||||
case U8X8_MSG_DELAY_MILLI: // delay arg_int * 1 milli second
|
||||
sleep_ms(arg_int);
|
||||
break;
|
||||
|
||||
// 8080 mode
|
||||
// D0 --> spi clock
|
||||
// D1 --> spi data
|
||||
if(u8x8->pins[U8X8_PIN_D2] != U8X8_PIN_NONE)
|
||||
{
|
||||
exportGPIOPin(u8x8->pins[U8X8_PIN_D2]);
|
||||
setGPIODirection(u8x8->pins[U8X8_PIN_D2], GPIO_OUT);
|
||||
setGPIOValue(u8x8->pins[U8X8_PIN_D2], GPIO_HIGH);
|
||||
}
|
||||
if(u8x8->pins[U8X8_PIN_D3] != U8X8_PIN_NONE)
|
||||
{
|
||||
exportGPIOPin(u8x8->pins[U8X8_PIN_D3]);
|
||||
setGPIODirection(u8x8->pins[U8X8_PIN_D3], GPIO_OUT);
|
||||
setGPIOValue(u8x8->pins[U8X8_PIN_D3], GPIO_HIGH);
|
||||
}
|
||||
if(u8x8->pins[U8X8_PIN_D4] != U8X8_PIN_NONE)
|
||||
{
|
||||
exportGPIOPin(u8x8->pins[U8X8_PIN_D4]);
|
||||
setGPIODirection(u8x8->pins[U8X8_PIN_D4], GPIO_OUT);
|
||||
setGPIOValue(u8x8->pins[U8X8_PIN_D4], GPIO_HIGH);
|
||||
}
|
||||
if(u8x8->pins[U8X8_PIN_D5] != U8X8_PIN_NONE)
|
||||
{
|
||||
exportGPIOPin(u8x8->pins[U8X8_PIN_D5]);
|
||||
setGPIODirection(u8x8->pins[U8X8_PIN_D5], GPIO_OUT);
|
||||
setGPIOValue(u8x8->pins[U8X8_PIN_D5], GPIO_HIGH);
|
||||
}
|
||||
if(u8x8->pins[U8X8_PIN_D6] != U8X8_PIN_NONE)
|
||||
{
|
||||
exportGPIOPin(u8x8->pins[U8X8_PIN_D6]);
|
||||
setGPIODirection(u8x8->pins[U8X8_PIN_D6], GPIO_OUT);
|
||||
setGPIOValue(u8x8->pins[U8X8_PIN_D6], GPIO_HIGH);
|
||||
}
|
||||
if(u8x8->pins[U8X8_PIN_D7] != U8X8_PIN_NONE)
|
||||
{
|
||||
exportGPIOPin(u8x8->pins[U8X8_PIN_D7]);
|
||||
setGPIODirection(u8x8->pins[U8X8_PIN_D7], GPIO_OUT);
|
||||
setGPIOValue(u8x8->pins[U8X8_PIN_D7], GPIO_HIGH);
|
||||
}
|
||||
if(u8x8->pins[U8X8_PIN_E] != U8X8_PIN_NONE)
|
||||
{
|
||||
exportGPIOPin(u8x8->pins[U8X8_PIN_E]);
|
||||
setGPIODirection(u8x8->pins[U8X8_PIN_E], GPIO_OUT);
|
||||
setGPIOValue(u8x8->pins[U8X8_PIN_E], GPIO_HIGH);
|
||||
}
|
||||
if(u8x8->pins[U8X8_PIN_RESET] != U8X8_PIN_NONE)
|
||||
{
|
||||
exportGPIOPin(u8x8->pins[U8X8_PIN_RESET]);
|
||||
setGPIODirection(u8x8->pins[U8X8_PIN_RESET], GPIO_OUT);
|
||||
setGPIOValue(u8x8->pins[U8X8_PIN_RESET], GPIO_HIGH);
|
||||
}
|
||||
if(u8x8->pins[U8X8_PIN_DC] != U8X8_PIN_NONE)
|
||||
{
|
||||
exportGPIOPin(u8x8->pins[U8X8_PIN_DC]);
|
||||
setGPIODirection(u8x8->pins[U8X8_PIN_DC], GPIO_OUT);
|
||||
setGPIOValue(u8x8->pins[U8X8_PIN_DC], GPIO_HIGH);
|
||||
}
|
||||
case U8X8_MSG_DELAY_I2C:
|
||||
// arg_int is the I2C speed in 100KHz, e.g. 4 = 400 KHz
|
||||
// arg_int=1: delay by 5us, arg_int = 4: delay by 1.25us
|
||||
if (arg_int == 1) {
|
||||
sleep_us(5);
|
||||
} else if (arg_int == 4) {
|
||||
sleep_ns(1250);
|
||||
}
|
||||
break;
|
||||
|
||||
// I2c pins
|
||||
if(u8x8->pins[U8X8_PIN_I2C_DATA] != U8X8_PIN_NONE)
|
||||
{
|
||||
exportGPIOPin(u8x8->pins[U8X8_PIN_I2C_DATA]);
|
||||
setGPIODirection(u8x8->pins[U8X8_PIN_I2C_DATA], GPIO_OUT);
|
||||
setGPIOValue(u8x8->pins[U8X8_PIN_I2C_DATA], GPIO_HIGH);
|
||||
}
|
||||
if(u8x8->pins[U8X8_PIN_I2C_CLOCK] != U8X8_PIN_NONE)
|
||||
{
|
||||
exportGPIOPin(u8x8->pins[U8X8_PIN_I2C_CLOCK]);
|
||||
setGPIODirection(u8x8->pins[U8X8_PIN_I2C_CLOCK], GPIO_OUT);
|
||||
setGPIOValue(u8x8->pins[U8X8_PIN_I2C_CLOCK], GPIO_HIGH);
|
||||
}
|
||||
case U8X8_MSG_GPIO_AND_DELAY_INIT:
|
||||
// Function which implements a delay, arg_int contains the amount of ms
|
||||
|
||||
break;
|
||||
// printf("CLK:%d, DATA:%d, CS:%d, RST:%d, DC:%d\n", u8x8->pins[U8X8_PIN_SPI_CLOCK], u8x8->pins[U8X8_PIN_SPI_DATA], u8x8->pins[U8X8_PIN_CS], u8x8->pins[U8X8_PIN_RESET], u8x8->pins[U8X8_PIN_DC]);
|
||||
// printf("SDA:%d, SCL:%d\n", u8x8->pins[U8X8_PIN_I2C_DATA], u8x8->pins[U8X8_PIN_I2C_CLOCK]);
|
||||
|
||||
//case U8X8_MSG_GPIO_D0: // D0 or SPI clock pin: Output level in arg_int
|
||||
//case U8X8_MSG_GPIO_SPI_CLOCK:
|
||||
// SPI Pins
|
||||
if (u8x8->pins[U8X8_PIN_SPI_CLOCK] != U8X8_PIN_NONE) {
|
||||
init_pin(u8x8, U8X8_PIN_SPI_CLOCK);
|
||||
}
|
||||
if (u8x8->pins[U8X8_PIN_SPI_DATA] != U8X8_PIN_NONE) {
|
||||
init_pin(u8x8, U8X8_PIN_SPI_DATA);
|
||||
}
|
||||
if (u8x8->pins[U8X8_PIN_CS] != U8X8_PIN_NONE) {
|
||||
init_pin(u8x8, U8X8_PIN_CS);
|
||||
}
|
||||
|
||||
//case U8X8_MSG_GPIO_D1: // D1 or SPI data pin: Output level in arg_int
|
||||
//case U8X8_MSG_GPIO_SPI_DATA:
|
||||
// 8080 mode
|
||||
// D0 --> spi clock
|
||||
// D1 --> spi data
|
||||
if (u8x8->pins[U8X8_PIN_D2] != U8X8_PIN_NONE) {
|
||||
init_pin(u8x8, U8X8_PIN_D2);
|
||||
}
|
||||
if (u8x8->pins[U8X8_PIN_D3] != U8X8_PIN_NONE) {
|
||||
init_pin(u8x8, U8X8_PIN_D3);
|
||||
}
|
||||
if (u8x8->pins[U8X8_PIN_D4] != U8X8_PIN_NONE) {
|
||||
init_pin(u8x8, U8X8_PIN_D4);
|
||||
}
|
||||
if (u8x8->pins[U8X8_PIN_D5] != U8X8_PIN_NONE) {
|
||||
init_pin(u8x8, U8X8_PIN_D5);
|
||||
}
|
||||
if (u8x8->pins[U8X8_PIN_D6] != U8X8_PIN_NONE) {
|
||||
init_pin(u8x8, U8X8_PIN_D6);
|
||||
}
|
||||
if (u8x8->pins[U8X8_PIN_D7] != U8X8_PIN_NONE) {
|
||||
init_pin(u8x8, U8X8_PIN_D7);
|
||||
}
|
||||
if (u8x8->pins[U8X8_PIN_E] != U8X8_PIN_NONE) {
|
||||
init_pin(u8x8, U8X8_PIN_E);
|
||||
}
|
||||
if (u8x8->pins[U8X8_PIN_RESET] != U8X8_PIN_NONE) {
|
||||
init_pin(u8x8, U8X8_PIN_RESET);
|
||||
}
|
||||
if (u8x8->pins[U8X8_PIN_DC] != U8X8_PIN_NONE) {
|
||||
init_pin(u8x8, U8X8_PIN_DC);
|
||||
}
|
||||
|
||||
case U8X8_MSG_GPIO_D2: // D2 pin: Output level in arg_int
|
||||
if(u8x8->pins[U8X8_PIN_D2] != U8X8_PIN_NONE)
|
||||
setGPIOValue(u8x8->pins[U8X8_PIN_D2], arg_int);
|
||||
break;
|
||||
// I2c pins
|
||||
if (u8x8->pins[U8X8_PIN_I2C_DATA] != U8X8_PIN_NONE) {
|
||||
init_pin(u8x8, U8X8_PIN_I2C_DATA);
|
||||
}
|
||||
if (u8x8->pins[U8X8_PIN_I2C_CLOCK] != U8X8_PIN_NONE) {
|
||||
init_pin(u8x8, U8X8_PIN_I2C_CLOCK);
|
||||
}
|
||||
|
||||
case U8X8_MSG_GPIO_D3: // D3 pin: Output level in arg_int
|
||||
if(u8x8->pins[U8X8_PIN_D3] != U8X8_PIN_NONE)
|
||||
setGPIOValue(u8x8->pins[U8X8_PIN_D3], arg_int);
|
||||
break;
|
||||
break;
|
||||
|
||||
case U8X8_MSG_GPIO_D4: // D4 pin: Output level in arg_int
|
||||
if(u8x8->pins[U8X8_PIN_D4] != U8X8_PIN_NONE)
|
||||
setGPIOValue(u8x8->pins[U8X8_PIN_D4], arg_int);
|
||||
break;
|
||||
//case U8X8_MSG_GPIO_D0: // D0 or SPI clock pin: Output level in arg_int
|
||||
//case U8X8_MSG_GPIO_SPI_CLOCK:
|
||||
|
||||
case U8X8_MSG_GPIO_D5: // D5 pin: Output level in arg_int
|
||||
if(u8x8->pins[U8X8_PIN_D5] != U8X8_PIN_NONE)
|
||||
setGPIOValue(u8x8->pins[U8X8_PIN_D5], arg_int);
|
||||
break;
|
||||
//case U8X8_MSG_GPIO_D1: // D1 or SPI data pin: Output level in arg_int
|
||||
//case U8X8_MSG_GPIO_SPI_DATA:
|
||||
|
||||
case U8X8_MSG_GPIO_D6: // D6 pin: Output level in arg_int
|
||||
if(u8x8->pins[U8X8_PIN_D6] != U8X8_PIN_NONE)
|
||||
setGPIOValue(u8x8->pins[U8X8_PIN_D6], arg_int);
|
||||
break;
|
||||
case U8X8_MSG_GPIO_D2: // D2 pin: Output level in arg_int
|
||||
if (u8x8->pins[U8X8_PIN_D2] != U8X8_PIN_NONE) {
|
||||
gpio_write(pins[U8X8_PIN_D2], arg_int);
|
||||
}
|
||||
break;
|
||||
|
||||
case U8X8_MSG_GPIO_D7: // D7 pin: Output level in arg_int
|
||||
if(u8x8->pins[U8X8_PIN_D7] != U8X8_PIN_NONE)
|
||||
setGPIOValue(u8x8->pins[U8X8_PIN_D7], arg_int);
|
||||
break;
|
||||
case U8X8_MSG_GPIO_D3: // D3 pin: Output level in arg_int
|
||||
if (u8x8->pins[U8X8_PIN_D3] != U8X8_PIN_NONE) {
|
||||
gpio_write(pins[U8X8_PIN_D3], arg_int);
|
||||
}
|
||||
break;
|
||||
|
||||
case U8X8_MSG_GPIO_E: // E/WR pin: Output level in arg_int
|
||||
if(u8x8->pins[U8X8_PIN_E] != U8X8_PIN_NONE)
|
||||
setGPIOValue(u8x8->pins[U8X8_PIN_E], arg_int);
|
||||
break;
|
||||
case U8X8_MSG_GPIO_D4: // D4 pin: Output level in arg_int
|
||||
if (u8x8->pins[U8X8_PIN_D4] != U8X8_PIN_NONE) {
|
||||
gpio_write(pins[U8X8_PIN_D4], arg_int);
|
||||
}
|
||||
break;
|
||||
|
||||
case U8X8_MSG_GPIO_I2C_CLOCK:
|
||||
// arg_int=0: Output low at I2C clock pin
|
||||
// arg_int=1: Input dir with pullup high for I2C clock pin
|
||||
if(u8x8->pins[U8X8_PIN_I2C_CLOCK] != U8X8_PIN_NONE)
|
||||
setGPIOValue(u8x8->pins[U8X8_PIN_I2C_CLOCK], arg_int);
|
||||
break;
|
||||
case U8X8_MSG_GPIO_D5: // D5 pin: Output level in arg_int
|
||||
if (u8x8->pins[U8X8_PIN_D5] != U8X8_PIN_NONE) {
|
||||
gpio_write(pins[U8X8_PIN_D5], arg_int);
|
||||
}
|
||||
break;
|
||||
|
||||
case U8X8_MSG_GPIO_I2C_DATA:
|
||||
// arg_int=0: Output low at I2C data pin
|
||||
// arg_int=1: Input dir with pullup high for I2C data pin
|
||||
if(u8x8->pins[U8X8_PIN_I2C_DATA] != U8X8_PIN_NONE)
|
||||
setGPIOValue(u8x8->pins[U8X8_PIN_I2C_DATA], arg_int);
|
||||
break;
|
||||
case U8X8_MSG_GPIO_D6: // D6 pin: Output level in arg_int
|
||||
if (u8x8->pins[U8X8_PIN_D6] != U8X8_PIN_NONE) {
|
||||
gpio_write(pins[U8X8_PIN_D6], arg_int);
|
||||
}
|
||||
break;
|
||||
|
||||
case U8X8_MSG_GPIO_SPI_CLOCK:
|
||||
//Function to define the logic level of the clockline
|
||||
if(u8x8->pins[U8X8_PIN_SPI_CLOCK] != U8X8_PIN_NONE)
|
||||
setGPIOValue(u8x8->pins[U8X8_PIN_SPI_CLOCK], arg_int);
|
||||
break;
|
||||
case U8X8_MSG_GPIO_D7: // D7 pin: Output level in arg_int
|
||||
if (u8x8->pins[U8X8_PIN_D7] != U8X8_PIN_NONE) {
|
||||
gpio_write(pins[U8X8_PIN_D7], arg_int);
|
||||
}
|
||||
break;
|
||||
|
||||
case U8X8_MSG_GPIO_SPI_DATA:
|
||||
//Function to define the logic level of the data line to the display
|
||||
if(u8x8->pins[U8X8_PIN_SPI_DATA] != U8X8_PIN_NONE)
|
||||
setGPIOValue(u8x8->pins[U8X8_PIN_SPI_DATA], arg_int);
|
||||
break;
|
||||
case U8X8_MSG_GPIO_E: // E/WR pin: Output level in arg_int
|
||||
if (u8x8->pins[U8X8_PIN_E] != U8X8_PIN_NONE) {
|
||||
gpio_write(pins[U8X8_PIN_E], arg_int);
|
||||
}
|
||||
break;
|
||||
|
||||
case U8X8_MSG_GPIO_I2C_CLOCK:
|
||||
// arg_int=0: Output low at I2C clock pin
|
||||
// arg_int=1: Input dir with pullup high for I2C clock pin
|
||||
if (u8x8->pins[U8X8_PIN_I2C_CLOCK] != U8X8_PIN_NONE) {
|
||||
gpio_write(pins[U8X8_PIN_I2C_CLOCK], arg_int);
|
||||
}
|
||||
break;
|
||||
|
||||
case U8X8_MSG_GPIO_I2C_DATA:
|
||||
// arg_int=0: Output low at I2C data pin
|
||||
// arg_int=1: Input dir with pullup high for I2C data pin
|
||||
if (u8x8->pins[U8X8_PIN_I2C_DATA] != U8X8_PIN_NONE) {
|
||||
gpio_write(pins[U8X8_PIN_I2C_DATA], arg_int);
|
||||
}
|
||||
break;
|
||||
|
||||
case U8X8_MSG_GPIO_SPI_CLOCK:
|
||||
//Function to define the logic level of the clockline
|
||||
if (u8x8->pins[U8X8_PIN_SPI_CLOCK] != U8X8_PIN_NONE) {
|
||||
gpio_write(pins[U8X8_PIN_SPI_CLOCK], arg_int);
|
||||
}
|
||||
break;
|
||||
|
||||
case U8X8_MSG_GPIO_SPI_DATA:
|
||||
//Function to define the logic level of the data line to the display
|
||||
if (u8x8->pins[U8X8_PIN_SPI_DATA] != U8X8_PIN_NONE) {
|
||||
gpio_write(pins[U8X8_PIN_SPI_DATA], arg_int);
|
||||
}
|
||||
break;
|
||||
|
||||
case U8X8_MSG_GPIO_CS:
|
||||
// Function to define the logic level of the CS line
|
||||
if(u8x8->pins[U8X8_PIN_CS] != U8X8_PIN_NONE)
|
||||
setGPIOValue(u8x8->pins[U8X8_PIN_CS], arg_int);
|
||||
break;
|
||||
// Function to define the logic level of the CS line
|
||||
if (u8x8->pins[U8X8_PIN_CS] != U8X8_PIN_NONE) {
|
||||
gpio_write(pins[U8X8_PIN_CS], arg_int);
|
||||
}
|
||||
break;
|
||||
|
||||
case U8X8_MSG_GPIO_DC:
|
||||
//Function to define the logic level of the Data/ Command line
|
||||
if(u8x8->pins[U8X8_PIN_DC] != U8X8_PIN_NONE)
|
||||
setGPIOValue(u8x8->pins[U8X8_PIN_DC], arg_int);
|
||||
break;
|
||||
case U8X8_MSG_GPIO_DC:
|
||||
//Function to define the logic level of the Data/ Command line
|
||||
if (u8x8->pins[U8X8_PIN_DC] != U8X8_PIN_NONE) {
|
||||
gpio_write(pins[U8X8_PIN_DC], arg_int);
|
||||
}
|
||||
break;
|
||||
|
||||
case U8X8_MSG_GPIO_RESET:
|
||||
//Function to define the logic level of the RESET line
|
||||
if(u8x8->pins[U8X8_PIN_RESET] != U8X8_PIN_NONE)
|
||||
setGPIOValue(u8x8->pins[U8X8_PIN_RESET], arg_int);
|
||||
break;
|
||||
case U8X8_MSG_GPIO_RESET:
|
||||
//Function to define the logic level of the RESET line
|
||||
if (u8x8->pins[U8X8_PIN_RESET] != U8X8_PIN_NONE) {
|
||||
gpio_write(pins[U8X8_PIN_RESET], arg_int);
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
return 1;
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
uint8_t u8x8_byte_arm_linux_hw_i2c(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr)
|
||||
{
|
||||
/* u8g2/u8x8 will never send more than 32 bytes between START_TRANSFER and END_TRANSFER */
|
||||
static uint8_t buffer[32];
|
||||
static uint8_t buf_idx;
|
||||
uint8_t *data;
|
||||
uint8_t u8x8_byte_arm_linux_hw_i2c(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int,
|
||||
void *arg_ptr) {
|
||||
/* u8g2/u8x8 will never send more than 32 bytes between START_TRANSFER and END_TRANSFER */
|
||||
static uint8_t buffer[32];
|
||||
static uint8_t buf_idx;
|
||||
uint8_t *data;
|
||||
|
||||
switch(msg)
|
||||
{
|
||||
case U8X8_MSG_BYTE_SEND:
|
||||
data = (uint8_t *)arg_ptr;
|
||||
while( arg_int > 0 )
|
||||
{
|
||||
buffer[buf_idx++] = *data;
|
||||
data++;
|
||||
arg_int--;
|
||||
}
|
||||
break;
|
||||
switch (msg) {
|
||||
case U8X8_MSG_BYTE_SEND:
|
||||
data = (uint8_t*) arg_ptr;
|
||||
while (arg_int > 0) {
|
||||
buffer[buf_idx++] = *data;
|
||||
data++;
|
||||
arg_int--;
|
||||
}
|
||||
break;
|
||||
|
||||
case U8X8_MSG_BYTE_INIT:
|
||||
i2c_device = openI2CDevice(i2c_bus);
|
||||
// printf("I2C File Descriptor: %d\n", fd);
|
||||
break;
|
||||
case U8X8_MSG_BYTE_INIT:
|
||||
i2c_device = openI2CDevice(i2c_bus);
|
||||
// printf("I2C File Descriptor: %d\n", fd);
|
||||
break;
|
||||
|
||||
case U8X8_MSG_BYTE_START_TRANSFER:
|
||||
setI2CSlave(i2c_device, u8x8_GetI2CAddress(u8x8)>>1);
|
||||
buf_idx = 0;
|
||||
// printf("I2C Address: %02x\n", u8x8_GetI2CAddress(u8x8)>>1);
|
||||
break;
|
||||
case U8X8_MSG_BYTE_START_TRANSFER:
|
||||
setI2CSlave(i2c_device, u8x8_GetI2CAddress(u8x8) >> 1);
|
||||
buf_idx = 0;
|
||||
// printf("I2C Address: %02x\n", u8x8_GetI2CAddress(u8x8)>>1);
|
||||
break;
|
||||
|
||||
case U8X8_MSG_BYTE_END_TRANSFER:
|
||||
I2CWriteBytes(i2c_device, buffer, buf_idx);
|
||||
break;
|
||||
case U8X8_MSG_BYTE_END_TRANSFER:
|
||||
I2CWriteBytes(i2c_device, buffer, buf_idx);
|
||||
break;
|
||||
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
return 1;
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
uint8_t u8x8_byte_arm_linux_hw_spi(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr)
|
||||
{
|
||||
uint8_t *data;
|
||||
uint8_t tx[2], rx[2];
|
||||
uint8_t internal_spi_mode;
|
||||
uint8_t u8x8_byte_arm_linux_hw_spi(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int,
|
||||
void *arg_ptr) {
|
||||
uint8_t *data;
|
||||
uint8_t tx[2], rx[2];
|
||||
uint8_t internal_spi_mode;
|
||||
|
||||
switch(msg)
|
||||
{
|
||||
case U8X8_MSG_BYTE_SEND:
|
||||
data = (uint8_t *)arg_ptr;
|
||||
// printf("Buffering Data %d \n", arg_int);
|
||||
switch (msg) {
|
||||
case U8X8_MSG_BYTE_SEND:
|
||||
data = (uint8_t*) arg_ptr;
|
||||
// printf("Buffering Data %d \n", arg_int);
|
||||
|
||||
while( arg_int > 0)
|
||||
{
|
||||
// printf("%.2X ", (uint8_t)*data);
|
||||
tx[0] = (uint8_t)*data;
|
||||
struct spi_ioc_transfer tr = {
|
||||
.tx_buf = (unsigned long)tx,
|
||||
.rx_buf = (unsigned long)rx,
|
||||
.len = 1,
|
||||
.delay_usecs = 0,
|
||||
.speed_hz = 500000,
|
||||
.bits_per_word = 8,
|
||||
};
|
||||
while (arg_int > 0) {
|
||||
// printf("%.2X ", (uint8_t)*data);
|
||||
tx[0] = (uint8_t) * data;
|
||||
struct spi_ioc_transfer tr = { .tx_buf = (unsigned long) tx,
|
||||
.rx_buf = (unsigned long) rx, .len = 1, .delay_usecs = 0,
|
||||
.speed_hz = 500000, .bits_per_word = 8, };
|
||||
|
||||
SPITransfer(spi_device, &tr);
|
||||
data++;
|
||||
arg_int--;
|
||||
}
|
||||
// printf("\n");
|
||||
break;
|
||||
SPITransfer(spi_device, &tr);
|
||||
data++;
|
||||
arg_int--;
|
||||
}
|
||||
// printf("\n");
|
||||
break;
|
||||
|
||||
case U8X8_MSG_BYTE_INIT:
|
||||
//u8x8_gpio_SetCS(u8x8, u8x8->display_info->chip_disable_level);
|
||||
/* SPI mode has to be mapped to the mode of the current controller, at least Uno, Due, 101 have different SPI_MODEx values */
|
||||
/* 0: clock active high, data out on falling edge, clock default value is zero, takover on rising edge */
|
||||
/* 1: clock active high, data out on rising edge, clock default value is zero, takover on falling edge */
|
||||
/* 2: clock active low, data out on rising edge */
|
||||
/* 3: clock active low, data out on falling edge */
|
||||
internal_spi_mode = 0;
|
||||
switch(u8x8->display_info->spi_mode)
|
||||
{
|
||||
case 0: break;
|
||||
case 1: internal_spi_mode |= SPI_CPHA; break;
|
||||
case 2: internal_spi_mode |= SPI_CPOL; break;
|
||||
case 3: internal_spi_mode |= SPI_CPOL; internal_spi_mode |= SPI_CPHA; break;
|
||||
}
|
||||
// printf("SPI Device Mode Set\n");
|
||||
case U8X8_MSG_BYTE_INIT:
|
||||
//u8x8_gpio_SetCS(u8x8, u8x8->display_info->chip_disable_level);
|
||||
/* SPI mode has to be mapped to the mode of the current controller, at least Uno, Due, 101 have different SPI_MODEx values */
|
||||
/* 0: clock active high, data out on falling edge, clock default value is zero, takover on rising edge */
|
||||
/* 1: clock active high, data out on rising edge, clock default value is zero, takover on falling edge */
|
||||
/* 2: clock active low, data out on rising edge */
|
||||
/* 3: clock active low, data out on falling edge */
|
||||
internal_spi_mode = 0;
|
||||
switch (u8x8->display_info->spi_mode) {
|
||||
case 0:
|
||||
break;
|
||||
case 1:
|
||||
internal_spi_mode |= SPI_CPHA;
|
||||
break;
|
||||
case 2:
|
||||
internal_spi_mode |= SPI_CPOL;
|
||||
break;
|
||||
case 3:
|
||||
internal_spi_mode |= SPI_CPOL;
|
||||
internal_spi_mode |= SPI_CPHA;
|
||||
break;
|
||||
}
|
||||
// printf("SPI Device Mode Set\n");
|
||||
|
||||
spi_device = openSPIDevice(spi_bus, internal_spi_mode, 8, 500000);
|
||||
if (spi_device < 0 )
|
||||
{
|
||||
printf("Failed to open SPI Device %s\n", spi_bus);
|
||||
}
|
||||
else
|
||||
{
|
||||
printf("SPI Device Opened\n");
|
||||
}
|
||||
break;
|
||||
spi_device = openSPIDevice(spi_bus, internal_spi_mode, 8, 500000);
|
||||
if (spi_device < 0) {
|
||||
printf("Failed to open SPI Device %s\n", spi_bus);
|
||||
} else {
|
||||
printf("SPI Device Opened\n");
|
||||
}
|
||||
break;
|
||||
|
||||
case U8X8_MSG_BYTE_SET_DC:
|
||||
u8x8_gpio_SetDC(u8x8, arg_int);
|
||||
break;
|
||||
case U8X8_MSG_BYTE_SET_DC:
|
||||
u8x8_gpio_SetDC(u8x8, arg_int);
|
||||
break;
|
||||
|
||||
case U8X8_MSG_BYTE_START_TRANSFER:
|
||||
break;
|
||||
case U8X8_MSG_BYTE_START_TRANSFER:
|
||||
break;
|
||||
|
||||
case U8X8_MSG_BYTE_END_TRANSFER:
|
||||
break;
|
||||
case U8X8_MSG_BYTE_END_TRANSFER:
|
||||
break;
|
||||
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
return 1;
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
|
|
@ -10,6 +10,7 @@
|
|||
#include "i2c.h"
|
||||
#include "spi.h"
|
||||
|
||||
void init_pin(u8x8_t *u8x8, int pin);
|
||||
uint8_t u8x8_arm_linux_gpio_and_delay(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr);
|
||||
uint8_t u8x8_byte_arm_linux_hw_i2c(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr);
|
||||
uint8_t u8x8_byte_arm_linux_hw_spi(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr);
|
||||
|
|
Loading…
Reference in New Issue