BB: update peripheral_manager

This commit is contained in:
Sukru Senli 2015-05-06 13:58:16 +02:00 committed by Martin Schröder
parent 1045dc2bdb
commit c365f00e7d
13 changed files with 601 additions and 173 deletions

View file

@ -25,9 +25,12 @@ peripheral_manager_SOURCES = \
src/i2c.c \
src/i2c.h \
src/sfp.c \
src/sfp.h
src/sfp.h
if BRCM_BOARD
bin_PROGRAMS += vox_test
peripheral_manager_SOURCES += \
src/gpio_led.c \
src/gpio_led.h \
@ -36,7 +39,15 @@ peripheral_manager_SOURCES += \
src/gpio.c \
src/gpio.h \
src/touch_sx9512.c \
src/touch_sx9512.h
src/touch_sx9512.h \
src/vox.h \
src/vox.c \
src/prox_px3220.c
vox_test_SOURCES = \
src/vox_test.c \
src/gpio.c \
src/gpio.h
endif
peripheral_manager_LDADD = $(UCI_LIB) $(UBOX_LIB) $(UBUS_LIB) -lm

View file

@ -1,129 +1,12 @@
# test config for peripheral_manager
# only contain options that peripheral_manager needs and that can be used
# when compiling to host (not target hardware)
config board 'board'
option hardware 'CG300'
option hasAdsl '0'
option hasVdsl '0'
option hasVoice '0'
option hasDect '1'
option VoicePorts '0'
option VoiceLeds '0'
option hasWifi '1'
option ethernetPorts '2'
option ethernetPortNames 'LAN WAN'
option ethernetPortOrder 'eth1 eth0'
option ethernetLanPorts 'eth1'
option ethernetWanPort 'eth0'
option adslWanPort ''
option vdslWanPort ''
# option lednames 'Status Internet Wireless WPS DECT WAN'
option lednames 'Status Internet Wireless WPS DECT WAN'
option buttonnames 'RESET Wireless WPS DECT TOUCH_NEAR TOUCH_FAR'
option wpsButtonGpio '0'
option fxsRelayGpio '0'
option i2cGpioCustom 'bus0=0,23,22'
config wifi-chip '435f'
option bands 'b'
config wifi-chip '43a0'
option bands 'a'
option is_ac '1'
config wifi-chip '43a2'
option bands 'a'
option is_ac '1'
config wifi-chip '43bc'
option bands 'a'
option is_ac '1'
option radarthrs '0x6ae 0x30 0x6a8 0x30 0x6a4 0x30 0x6aa 0x30 0x6aa 0x30 0x6a4 0x30'
config buttons 'buttons'
option RESET 'gpio 32 al resetbutton Status_green'
option DECT 'i2c 3 ah dectbutton WPS_green'
option WPS 'i2c 2 ah wpsbutton Wireless_green'
option Wireless 'i2c 1 ah ecobutton Internet_green'
option TOUCH_NEAR 'i2c 8 ah touch_near Wireless_blue'
option TOUCH_FAR 'i2c 9 ah touch_far Internet_red'
config leds 'leds'
option Status_green 'gpio 39 al'
option Status_red 'gpio 38 al'
option Internet_green 'i2c 4 ah'
option Internet_red 'i2c 5 ah'
option Wireless_green 'gpio 37 al'
option Wireless_blue 'gpio 36 al'
option WPS_green 'i2c 2 ah'
option DECT_green 'i2c 3 ah'
option WAN_green 'gpio 9 al'
option WAN_yellow 'gpio 10 al'
# config led_map 'led_map'
# option dsl_ok ''
# option dsl_off ''
# option dsl_notice ''
# option dsl_alert ''
# option dsl_error ''
# option wifi_ok 'Wireless_green=ON Wireless_blue=OFF'
# option wifi_off 'Wireless_green=OFF Wireless_blue=OFF'
# option wifi_notice 'Wireless_green=OFF Wireless_blue=ON'
# option wifi_alert 'Wireless_green=OFF Wireless_blue=ON'
# option wifi_error 'Wireless_green=OFF Wireless_blue=BLINK_FAST'
# option wps_ok 'WPS_green=ON'
# option wps_off 'WPS_green=OFF'
# option wps_notice 'WPS_green=BLINK_SLOW'
# option wps_alert 'WPS_green=OFF'
# option wps_error 'WPS_green=OFF'
# option lan_ok ''
# option lan_off ''
# option lan_notice ''
# option lan_alert ''
# option lan_error ''
# option status_ok 'Status_green=ON Status_red=OFF'
# option status_off 'Status_green=OFF Status_red=OFF'
# option status_notice 'Status_green=BLINK_SLOW Status_red=OFF'
# option status_alert 'Status_green=OFF Status_red=BLINK_SLOW'
# option status_error 'Status_green=OFF Status_red=BLINK_FAST'
# option dect_ok 'DECT_green=ON'
# option dect_off 'DECT_green=OFF'
# option dect_notice 'DECT_green=BLINK_SLOW'
# option dect_alert 'DECT_green=OFF'
# option dect_error 'DECT_green=OFF'
# option tv_ok ''
# option tv_off ''
# option tv_notice ''
# option tv_alert ''
# option tv_error ''
# option usb_ok ''
# option usb_off ''
# option usb_notice ''
# option usb_alert ''
# option usb_error ''
# option wan_ok ''
# option wan_off 'WAN_green=OFF WAN_yellow=OFF'
# option wan_notice 'WAN_green=ON'
# option wan_alert 'WAN_yellow=ON'
# option wan_error ''
# option internet_ok 'Internet_green=ON Internet_red=OFF'
# option internet_off 'Internet_green=OFF Internet_red=OFF'
# option internet_notice 'Internet_green=BLINK_SLOW Internet_red=OFF'
# option internet_alert 'Internet_green=OFF Internet_red=BLINK_SLOW'
# option internet_error 'Internet_green=OFF Internet_red=BLINK_FAST'
# option voice1_ok ''
# option voice1_off ''
# option voice1_notice ''
# option voice1_alert ''
# option voice1_error ''
# option voice2_ok ''
# option voice2_off ''
# option voice2_notice ''
# option voice2_alert ''
# option voice2_error ''
# option eco_ok ''
# option eco_off ''
# option eco_notice ''
# option eco_alert ''
# option eco_error ''
# for CATV parsing we need this hardware
# option hardware 'EG300'
###############################################################################
#
@ -301,49 +184,63 @@ config gpio_button gpio_reset
#
config led_map led_map
list functions status
list functions wifi
list functions wps
config led_map led_status
list led_action_ok 'sim_led_A = ON'
list led_action_ok 'sim_led_B = OFF'
list led_action_off 'sim_led_A = OFF'
list led_action_off 'sim_led_B = OFF'
list led_action_notice 'sim_led_A = FLASH_SLOW'
list led_action_notice 'sim_led_B = OFF'
list led_action_alert 'sim_led_A = OFF'
list led_action_alert 'sim_led_B = FLASH_SLOW'
list led_action_error 'sim_led_A = OFF'
list led_action_error 'sim_led_B = FLASH_FAST'
config led_map led_wps
# list led_action_ok 'WPS_green=ON'
# list led_action_off 'WPS_green=OFF'
# list led_action_notice 'WPS_green=FLASH_SLOW'
# list led_action_alert 'WPS_green=FLASH_FAST'
# list led_action_error 'WPS_green=OFF'
config led_map led_wifi
# list led_action_ok 'Wireless_green = ON'
# list led_action_ok 'Wireless_blue = OFF'
# list led_action_eok 'Wireless_green = OFF'
# list led_action_eok 'Wireless_blue = ON'
# list led_action_off 'Wireless_green = OFF'
# list led_action_off 'Wireless_blue = OFF'
# list led_action_notice 'Wireless_green = FLASH_SLOW'
# list led_action_notice 'Wireless_blue = OFF'
# list led_action_alert 'Wireless_green = OFF'
# list led_action_alert 'Wireless_blue = FLASH_SLOW'
# list led_action_error 'Wireless_green = OFF'
# list led_action_error 'Wireless_blue = FLASH_FAST'
###############################################################################
#
# function superfunctions
#
# Used when one led is controlled by seferal different functions
# here we map in what state the underlying normal functions should have
# to set a state, and what action to take in that state.
config led_map status_ok
list led_action Status_green=ON
list led_action Status_red=OFF
config led_map status_off
list led_action Status_green=OFF
list led_action Status_red=OFF
config led_map status_notice
list led_action Status_green=FLASH_SLOW
list led_action Status_red=OFF
config led_map status_alert
list led_action Status_green=
list led_action Status_red=FLASH_SLOW
config led_map status_error
list led_action Status_green=OFF
list led_action Status_red=FLASH_FAST
# list available super functions.
config led_map led_map
list functions super_a
config led_map led_super_a
list led_action_ok sim_led_C=ON
list super_ok 'wifi_ok, wps_ok'
config led_map wifi_ok
list led_action sim_led_A=ON
list led_action sim_led_C=OFF
config led_map wifi_off
list led_action sim_led_A=OFF
list led_action sim_led_C=OFF
config led_map wifi_notice
list led_action sim_led_A=OFF
list led_action sim_led_C=ON
config led_map wifi_alert
list led_action sim_led_A=OFF
list led_action sim_led_C=ON
config led_map wifi_error
list led_action sim_led_A=FLASH_SLOW
list led_action sim_led_C=FLASH_SLOW
config led_map wps_ok
list led_action sim_led_B=ON
config led_map wps_off
list led_action sim_led_B=OFF
config led_map wps_notice
list led_action sim_led_B=ON
config led_map wps_alert
list led_action sim_led_B=ON
config led_map wps_error
list led_action sim_led_B=ON
list led_action_off sim_led_C=OFF
list super_off 'wifi_off, wps_off'
list led_action_notice sim_led_C=FLASH_SLOW
list super_notice 'wifi_notice'
list super_notice 'wps_notice'

View file

@ -6,6 +6,7 @@
#include "button.h"
#include "led.h"
#include "touch_sx9512.h"
#include "prox_px3220.h"
/* used to map in the driver buttons to a function button */
struct button_drv_list {
@ -168,6 +169,8 @@ static void button_handler(struct uloop_timeout *timeout)
/* sx9512 driver needs to read out all buttons at once */
/* so call it once at beginning of scanning inputs */
sx9512_check();
/* same for px3220 */
px3220_check();
#endif
/* clean out indicator status, set by any valid press again if we find it */

View file

@ -61,7 +61,7 @@ static int is_enabled(void)
int ret;
if (ubus_lookup_id(ubus_ctx, "catv", &id)) {
DBG(1, "Failed to look up catv object\n");
DBG(4, "Failed to look up catv object\n");
return 0;
}

View file

@ -96,7 +96,7 @@ static int gpio_set_state(struct led_drv *drv, led_state_t state)
shift_register3_set(p->addr, bit_val);
break;
default:
DBG(1,"access mode not supported [%d]", p->mode);
DBG(1,"access mode not supported [%d,%s]", p->mode, p->led.name);
}
return p->state;
@ -150,6 +150,8 @@ void gpio_led_init(struct server_ctx *s_ctx) {
data->mode = SHIFTREG2;
else if (!strncasecmp("csr",s,4))
data->mode = SHIFTREG3;
else
DBG(1, "Mode %s : Not supported!", s);
}
s = ucix_get_option(s_ctx->uci_ctx, "hw" , data->led.name, "active");

View file

@ -8,9 +8,10 @@ typedef enum {
ON,
FLASH_SLOW,
FLASH_FAST,
BREADING,
PULSING,
FADEON,
FADEOFF,
NEED_INIT, /* set on loading config */
LED_STATES_MAX,
} led_state_t;
@ -30,6 +31,7 @@ struct led_drv_func{
led_state_t (*get_state)(struct led_drv *); /* Get led state, on,off,flash ... */
int (*set_color)(struct led_drv *, led_color_t); /* Set led color */
led_color_t (*get_color)(struct led_drv *); /* Get led color */
int (*support) (struct led_drv *, led_state_t); /* do driver has hardware support for state */
};
struct led_drv {

View file

@ -0,0 +1,198 @@
#include <syslog.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <sys/ioctl.h>
#include <board.h>
#include "button.h"
#include "smbus.h"
#include <linux/i2c.h>
#include <linux/i2c-dev.h>
#include "ucix.h"
#include "i2c.h"
#include "log.h"
#include "gpio.h"
#include "prox_px3220.h"
/* register names, from page 29, */
#define PX3220_SYSCONF 0x00
#define PX3220_IRQ_STATUS 0x01
#define PX3220_IRQ_CLEAR 0x02
#define PX3220_IR_DATA_LOW 0x0A
#define PX3220_IR_DATA_HIGH 0x0B
#define PX3220_PS_DATA_LOW 0x0E
#define PX3220_PS_DATA_HIGH 0x0F
#define PX3220_PS_LOW_THRESH_L 0x2A
#define PX3220_PS_LOW_THRESH_H 0x2B
#define PX3220_PS_HIGH_THRESH_L 0x2C
#define PX3220_PS_HIGH_THRESH_H 0x2D
#define IRQ_BUTTON 33
struct i2c_reg_tab {
char addr;
char value;
char range; /* if set registers starting from addr to addr+range will be set to the same value */
};
struct button_data {
int addr;
int state;
struct button_drv button;
};
static const struct i2c_reg_tab i2c_init_tab_vox25[]={
{PX3220_SYSCONF, 0x04, 0x00 }, /* Reset */
{PX3220_SYSCONF, 0x02, 0x00 }, /* Power on IR */
{PX3220_IRQ_STATUS, 0x01, 0x00 },
{0x20, 0x17, 0x00 },
{0x23, 0x03, 0x00 },
{PX3220_PS_LOW_THRESH_L, 0x00, 0x00 },
{PX3220_PS_LOW_THRESH_H, 0x18, 0x00 },
{PX3220_PS_HIGH_THRESH_L, 0x00, 0x00 },
{PX3220_PS_HIGH_THRESH_H, 0x14, 0x00 },
};
int dev;
int shadow_proximity;
void do_init_tab(const struct i2c_reg_tab *tab, int len );
void do_init_tab(const struct i2c_reg_tab *tab, int len )
{
int i;
for (i = 0 ; i < len ; i++){
int y;
int ret;
for ( y = 0 ; y <= tab[i].range; y++ ){
DBG(3,"%s: addr %02X = %02X ",__func__,(unsigned char)tab[i].addr+y, (unsigned char)tab[i].value);
ret = i2c_smbus_write_byte_data(dev, tab[i].addr+y, tab[i].value);
if (ret < 0){
perror("write to i2c dev\n");
}
}
}
}
void px3220_check(void)
{
int got_irq;
unsigned short reg_low, reg_high, ps_val;
shadow_proximity = 0;
if (dev){
got_irq = board_ioctl( BOARD_IOCTL_GET_GPIO, 0, 0, NULL, IRQ_BUTTON, 0);
/* got_irq is active low */
if (!got_irq) {
reg_low = i2c_smbus_read_byte_data(dev, PX3220_PS_DATA_LOW);
reg_high = i2c_smbus_read_byte_data(dev, PX3220_PS_DATA_HIGH);
ps_val = ((reg_high & 0x3F) << 4) | (reg_low & 0xF);
if (ps_val > 0x58)
shadow_proximity |= 0x1;
else
shadow_proximity |= 0x2;
}
}
if (shadow_proximity)
DBG(1,"shadow_proximity [%x]", shadow_proximity);
}
static button_state_t px3220_button_get_state(struct button_drv *drv)
{
struct button_data *p = (struct button_data *)drv->priv;
if (p->addr == 0 ){
if (shadow_proximity & 1 ) {
shadow_proximity &= ~0x1;
p->state = PRESSED;
return PRESSED;
}
}
if (p->addr == 1 ){
if (shadow_proximity & 2 ) {
shadow_proximity &= ~0x2;
p->state = PRESSED;
return PRESSED;
}
}
p->state = RELEASED;
return p->state;
}
static struct button_drv_func button_func = {
.get_state = px3220_button_get_state,
};
void px3220_init(struct server_ctx *s_ctx) {
const char *p;
struct ucilist *node;
LIST_HEAD(buttons);
DBG(1, "");
p = ucix_get_option(s_ctx->uci_ctx, "hw", "board", "hardware");
if (p == 0){
syslog(LOG_INFO, "%s: Missing Hardware identifier in configuration. I2C is not started\n",__func__);
return;
}
/* Driver only existfor VOX25 board */
if (strcmp("VOX25", p))
return;
/* open i2c device */
dev = i2c_open_dev("/dev/i2c-0", 0x1E,
I2C_FUNC_SMBUS_READ_BYTE | I2C_FUNC_SMBUS_WRITE_BYTE);
if (dev < 0) {
syslog(LOG_INFO,"%s: could not open i2c touch device\n",__func__);
dev = 0;
return;
}
do_init_tab(i2c_init_tab_vox25, sizeof(i2c_init_tab_vox25)/sizeof(struct i2c_reg_tab));
/* read config file */
ucix_get_option_list(s_ctx->uci_ctx, "hw" ,"3220_buttons", "buttons", &buttons);
list_for_each_entry(node, &buttons, list) {
struct button_data *data;
const char *s;
DBG(1, "value = [%s]",node->val);
data = malloc(sizeof(struct button_data));
memset(data,0,sizeof(struct button_data));
data->button.name = node->val;
s = ucix_get_option(s_ctx->uci_ctx, "hw" , data->button.name, "addr");
DBG(1, "addr = [%s]", s);
if (s){
data->addr = strtol(s,0,0);
}
data->button.func = &button_func;
data->button.priv = data;
button_add(&data->button);
}
}

View file

@ -0,0 +1,9 @@
#ifndef PROX_PX3220_H
#define PROX_PX3220_H
#include "server.h"
void px3220_init(struct server_ctx *);
void px3220_check(void);
#endif /* PROX_PX3220_H */

View file

@ -7,6 +7,7 @@
#include "catv.h"
#include "sfp.h"
#include "touch_sx9512.h"
#include "prox_px3220.h"
struct server_ctx server;
@ -17,6 +18,7 @@ void gpio_led_init(struct server_ctx *);
void gpio_button_init(struct server_ctx *);
void catv_monitor_init(struct server_ctx *);
void vox_init(struct server_ctx *);
struct catv_handler *catv_h;
struct sfp_handler *sfp_h;
@ -38,6 +40,10 @@ void server_start(struct uci_context *uci_ctx, struct ubus_context *ubus_ctx)
gpio_button_init(&server);
sx9512_init(&server);
px3220_init(&server);
vox_init(&server);
#endif
DBG(1, "connect generic buttons/leds to hardware drivers.");

View file

@ -827,6 +827,7 @@ static int ddm_prepare(void)
return 1;
};
#if 0
static int sfp_ddm_get_temperature(struct blob_buf *b, int raw)
{
float x;
@ -860,6 +861,7 @@ static int sfp_ddm_get_temperature_method(struct ubus_context *ubus_ctx, struct
ubus_send_reply(ubus_ctx, req, b.head);
return 0;
}
#endif
static int sfp_ddm_get_voltage(struct blob_buf *b, int raw)
{

View file

@ -41,11 +41,10 @@ struct sim_data {
int addr;
led_color_t color;
int state;
int breading;
int pulsing;
struct led_drv led;
};
void sim_led_init(struct server_ctx *s_ctx) {
LIST_HEAD(leds);
@ -86,11 +85,11 @@ void sim_led_init(struct server_ctx *s_ctx) {
}
DBG(1, "color = [%s]=(%d)", s,data->color);
s = ucix_get_option(s_ctx->uci_ctx, "hw" , data->led.name, "breading");
DBG(1, "breading = [%s]", s);
s = ucix_get_option(s_ctx->uci_ctx, "hw" , data->led.name, "pulsing");
DBG(1, "pulsing = [%s]", s);
if (s){
if (!strncasecmp("yes",s,3))
data->breading = 1;
data->pulsing = 1;
}
data->led.func = &func;
data->led.priv = data;

View file

@ -0,0 +1,127 @@
#include <syslog.h>
#include <string.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <sys/ioctl.h>
#include <board.h>
#include "log.h"
#include "server.h"
#include "led.h"
#include "gpio.h"
#define SPI_SLAVE_SELECT 1
struct vox_data {
int addr;
led_state_t state;
struct led_drv led;
};
void vox_init(struct server_ctx *s_ctx);
static int vox_set_state(struct led_drv *drv, led_state_t state)
{
struct vox_data *p = (struct vox_data *)drv->priv;
char spi_data[6] = {0,0,0,0,0,0};
if (p->state == state)
return state;
spi_data[0] = p->addr;
if (state == ON) {
spi_data[1] = 1;
spi_data[2] = 0x0;
spi_data[3] = 0x0;
spi_data[4] = 0x0;
spi_data[4] = 0x0;
} else if(state == PULSING) {
spi_data[1] = 3;
spi_data[2] = 0xa0;
} else if(state == FLASH_SLOW) {
spi_data[1] = 2;
spi_data[3] = 0x95;
} else if(state == FLASH_FAST) {
spi_data[1] = 2;
spi_data[3] = 0x20;
}
DBG(1,"vox_set_state %x %x %x %x",spi_data[0],spi_data[1],spi_data[2],spi_data[3]);
board_ioctl(BOARD_IOCTL_SPI_WRITE, SPI_SLAVE_SELECT, 0, spi_data, 6, 0);
p->state = state;
return state;
}
static led_state_t vox_get_state(struct led_drv *drv)
{
struct vox_data *p = (struct vox_data *)drv->priv;
return p->state;
}
static int vox_support(struct led_drv *drv, led_state_t state)
{
switch (state) {
case OFF:
case ON:
case FLASH_SLOW:
case FLASH_FAST:
case PULSING:
return 1;
break;
default:
return 0;
}
return 0;
}
static struct led_drv_func func = {
.set_state = vox_set_state,
.get_state = vox_get_state,
.support = vox_support,
};
void vox_init(struct server_ctx *s_ctx) {
LIST_HEAD(leds);
struct ucilist *node;
int register_spi = 0;
DBG(1, "");
ucix_get_option_list(s_ctx->uci_ctx, "hw" ,"vox_leds", "leds", &leds);
list_for_each_entry(node,&leds,list){
struct vox_data *data;
const char *s;
DBG(1, "value = [%s]",node->val);
data = malloc(sizeof(struct vox_data));
memset(data,0,sizeof(struct vox_data));
data->led.name = node->val;
s = ucix_get_option(s_ctx->uci_ctx, "hw" , data->led.name, "addr");
DBG(1, "addr = [%s]", s);
if (s) {
data->addr = strtol(s,0,0);
}else
syslog(LOG_ERR,"vox_led config needs addr option\n");
data->led.func = &func;
data->led.priv = data;
data->state = NEED_INIT;
led_add(&data->led);
register_spi = 1;
}
/* if config entries for vox leds exist register the spi as used. */
if(register_spi) {
board_ioctl(BOARD_IOCTL_SPI_INIT, SPI_SLAVE_SELECT, 0, 0, 0, 391000);
gpio_open_ioctl();
}
}

View file

@ -0,0 +1,172 @@
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <sys/select.h>
#include <termios.h>
#include <board.h>
#include "gpio.h"
int debug_level;
struct termios orig_termios;
#define SPI_SLAVE_SELECT 1
void reset_terminal_mode(void);
void set_conio_terminal_mode( void );
int kbhit( void );
int getch( void );
void display(void);
void inc(void);
void dec(void);
void reset_terminal_mode( void)
{
tcsetattr(0, TCSANOW, &orig_termios);
}
void set_conio_terminal_mode( void )
{
struct termios new_termios;
/* take two copies - one for now, one for later */
tcgetattr(0, &orig_termios);
memcpy(&new_termios, &orig_termios, sizeof(new_termios));
/* register cleanup handler, and set the new terminal mode */
atexit(reset_terminal_mode);
cfmakeraw(&new_termios);
tcsetattr(0, TCSANOW, &new_termios);
}
int kbhit( void )
{
struct timeval tv = { 0L, 0L };
fd_set fds;
FD_ZERO(&fds);
FD_SET(0, &fds);
return select(1, &fds, NULL, NULL, &tv);
}
int getch( void )
{
int r = 0;
int c = 0;
if ((r = read(0, &c, sizeof(c))) < 0) {
return r;
} else {
#if __BYTE_ORDER == __BIG_ENDIAN
int ret = 0;
ret |= (c >> 24) & 0x000000ff;
ret |= (c >> 8) & 0x0000ff00;
ret |= (c << 8) & 0x00ff0000;
ret |= (c << 24) & 0xff000000;
return ret;
#else
return c;
#endif
}
}
unsigned char spi_data [6] = {8,3,0,0,0,0};
int pos;
void display(void){
printf("\r");
printf("%02x %02x %02x %02x \r",
spi_data[2],
spi_data[3],
spi_data[4],
spi_data[5]
);
if (pos){
int jump = pos/2;
printf("\e[%dC",pos+jump);
}
fflush(stdout);
}
void inc(void){
int byte = 2 + pos/2;
int nibble = pos%2;
int val_hi = (spi_data[byte] >> 4 ) & 0xF;
int val_lo = spi_data[byte] & 0xF;
if(!nibble) {
val_hi++;
if(val_hi > 0xF )
val_hi = 0xf;
}else{
val_lo++;
if(val_lo > 0xF )
val_lo = 0xf;
}
spi_data[byte] = val_hi << 4 | val_lo;
}
void dec(void){
int byte = 2 + pos/2;
int nibble = pos%2;
int val_hi = (spi_data[byte] >> 4 ) & 0xF;
int val_lo = spi_data[byte] & 0xF;
if(!nibble) {
val_hi--;
if(val_hi < 0 )
val_hi = 0;
}else{
val_lo--;
if(val_lo < 0 )
val_lo = 0;
}
spi_data[byte] = val_hi << 4 | val_lo;
}
int main(int argc, char *argv[])
{
int ch;
gpio_open_ioctl();
board_ioctl(BOARD_IOCTL_SPI_INIT, SPI_SLAVE_SELECT, 0, 0, 0, 391000);
set_conio_terminal_mode();
fflush(stdout);
display();
while ( 'q' != (char)(ch = getch())) {
/* right */
if (ch == 4414235) {
pos++;
if (pos > 7)
pos = 7;
}
/* left */
if (ch == 4479771) {
pos--;
if (pos < 0)
pos = 0;
}
/* up */
if (ch == 4283163) {
inc();
board_ioctl(BOARD_IOCTL_SPI_WRITE, SPI_SLAVE_SELECT, 0, (char*)spi_data, 6, 0);
}
/* down */
if (ch == 4348699) {
dec();
board_ioctl(BOARD_IOCTL_SPI_WRITE, SPI_SLAVE_SELECT, 0, (char*)spi_data, 6, 0);
}
display();
}
return 0;
}