nmhw21: prepare UI v2.0 implementation
This commit is contained in:
parent
c0550c87fb
commit
a962411cbf
|
|
@ -14,11 +14,52 @@
|
||||||
|
|
||||||
#include "ui.h"
|
#include "ui.h"
|
||||||
|
|
||||||
|
/* TODO: Define as masks */
|
||||||
|
/* HW V1.0: PCA9539BS (16 Bit) */
|
||||||
|
#define UI_V1_TOP_LED_GREEN 6
|
||||||
|
#define UI_V1_TOP_LED_RED 7
|
||||||
|
#define UI_V1_BOTTOM_LED_GREEN 9
|
||||||
|
#define UI_V1_BOTTOM_LED_RED 8
|
||||||
|
|
||||||
static int ui_i2c_bus = 0;
|
/* HW V2.0: PCA9538ABS (8 Bit) */
|
||||||
static int ui_bus_claimed = false;
|
#define UI_V2_ID_0 0
|
||||||
|
#define UI_V2_ID_1 1
|
||||||
|
#define UI_V2_TOP_LED_GREEN 2
|
||||||
|
#define UI_V2_TOP_LED_RED 3
|
||||||
|
#define UI_V2_BOTTOM_LED_GREEN 6
|
||||||
|
#define UI_V2_BOTTOM_LED_RED 5
|
||||||
|
|
||||||
|
|
||||||
|
#define PCA9538_OUT_REG 0x01
|
||||||
|
#define PCA9538_CONF_REG 0x03
|
||||||
|
|
||||||
|
#define PCA9539_OUT_REG 0x02
|
||||||
|
#define PCA9539_CONF_REG 0x06
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
static int ioext_i2c_bus = 0;
|
||||||
|
|
||||||
|
/* -1: unitialized, 0: UI not available, 1: UI V1.x, 2: UI V2.x */
|
||||||
|
static int hw_version = -1;
|
||||||
|
static int bus_claimed = 0;
|
||||||
|
|
||||||
|
static uint8_t out_reg[2];
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
static void set_output(uint bit, bool state)
|
||||||
|
{
|
||||||
|
if (state) {
|
||||||
|
out_reg[bit/8U] &= ~(1U << (bit % 8U));
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
out_reg[bit/8U] |= (1U << (bit % 8U));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static int switch_i2c_bus(int* old_bus)
|
static int switch_i2c_bus(int* old_bus)
|
||||||
{
|
{
|
||||||
int ret = 0;
|
int ret = 0;
|
||||||
|
|
@ -27,92 +68,152 @@ static int switch_i2c_bus(int* old_bus)
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
*old_bus = i2c_get_bus_num();
|
*old_bus = i2c_get_bus_num();
|
||||||
if (*old_bus != ui_i2c_bus) {
|
if (*old_bus != ioext_i2c_bus) {
|
||||||
ret = i2c_set_bus_num(ui_i2c_bus);
|
ret = i2c_set_bus_num(ioext_i2c_bus);
|
||||||
}
|
}
|
||||||
|
|
||||||
ui_bus_claimed = true;
|
bus_claimed++;
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int revert_i2c_bus(int bus)
|
static void revert_i2c_bus(int bus)
|
||||||
{
|
{
|
||||||
int ret = 0;
|
if (ioext_i2c_bus != bus) {
|
||||||
if (ui_i2c_bus != bus) {
|
(void)i2c_set_bus_num(bus);
|
||||||
ret = i2c_set_bus_num(bus);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
ui_bus_claimed = false;
|
bus_claimed--;
|
||||||
return ret;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void detect_version(void)
|
||||||
void ui_i2c_init(int i2c_bus)
|
|
||||||
{
|
|
||||||
ui_i2c_bus = i2c_bus;
|
|
||||||
}
|
|
||||||
|
|
||||||
int ui_claim_i2c_bus(int* old_bus)
|
|
||||||
{
|
|
||||||
return switch_i2c_bus(old_bus);
|
|
||||||
}
|
|
||||||
|
|
||||||
int ui_release_i2c_bus(int bus)
|
|
||||||
{
|
|
||||||
return revert_i2c_bus(bus);
|
|
||||||
}
|
|
||||||
|
|
||||||
static int ui_i2c_get_reg(uint32_t reg, u8* val, int version)
|
|
||||||
{
|
{
|
||||||
int ret;
|
int ret;
|
||||||
u8 temp;
|
uint8_t temp = 0;
|
||||||
|
|
||||||
/* Argument check */
|
hw_version = 0;
|
||||||
if ((reg >= 8)) {
|
|
||||||
return -1;
|
/* Try to detect PCA9539 on V1.x HW */
|
||||||
|
ret = i2c_read(CONFIG_UI_V1_I2C_ADDR, 0x00, 1, &temp, 1);
|
||||||
|
if (ret == 0) {
|
||||||
|
hw_version = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* State check. Has bus been claimed */
|
if (hw_version == 0) {
|
||||||
if (ui_bus_claimed == false) {
|
/* Try to detect PCA9538 on V2.x HW */
|
||||||
return -2;
|
ret = i2c_read(CONFIG_UI_V2_I2C_ADDR, 0x00, 1, &temp, 1);
|
||||||
|
if (ret == 0) {
|
||||||
|
hw_version = 2;
|
||||||
}
|
}
|
||||||
|
|
||||||
*val = 0;
|
|
||||||
if (version == 2) {
|
|
||||||
ret = i2c_read(CONFIG_UIV2_I2C_ADDR, reg & 0xFF, 1, &temp, 1);
|
|
||||||
}
|
}
|
||||||
else{
|
|
||||||
ret = i2c_read(CONFIG_UI_I2C_ADDR, reg & 0xFF, 1, &temp, 1);
|
|
||||||
}
|
|
||||||
if (ret == 0)
|
|
||||||
*val = temp;
|
|
||||||
|
|
||||||
return ret;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* version 2: V2.0 UI , 1: V1.0 UI */
|
static void init_io(void)
|
||||||
int detect_ui(void)
|
|
||||||
{
|
{
|
||||||
int bus;
|
switch (hw_version) {
|
||||||
int claim;
|
case 1: {
|
||||||
uint8_t val;
|
uint8_t dir[2] = { 0x00, 0x00 }; /* All IOs = Outputs */
|
||||||
static int ui_detected = -1; /* -1: unitialized, 0: UI not available, 1: UI V1 detected ,2: UI V2 detected */
|
(void)i2c_write(CONFIG_UI_V1_I2C_ADDR, PCA9539_CONF_REG, 1, dir, 2);
|
||||||
if (ui_detected < 0) {
|
|
||||||
claim = ui_claim_i2c_bus(&bus);
|
out_reg[0] = 0xFF;
|
||||||
if (claim == 0) {
|
out_reg[1] = 0xFF;
|
||||||
if ( 0 == ui_i2c_get_reg(0x00, &val,1))
|
break;
|
||||||
ui_detected = 1;
|
|
||||||
else {
|
|
||||||
if ( 0 == ui_i2c_get_reg(0x00, &val,2))
|
|
||||||
ui_detected = 2;
|
|
||||||
else
|
|
||||||
ui_detected = 0;
|
|
||||||
}
|
}
|
||||||
ui_release_i2c_bus(bus);
|
|
||||||
|
case 2: {
|
||||||
|
uint8_t dir[1] = { 0x03 }; /* Keep IO 0 & 1 as inputs */
|
||||||
|
(void)i2c_write(CONFIG_UI_V2_I2C_ADDR, PCA9538_CONF_REG, 1, dir, 1);
|
||||||
|
|
||||||
|
out_reg[0] = 0xFF;
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
default:
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
return ui_detected;
|
}
|
||||||
|
|
||||||
|
static void v1_set_top_leds(int red, int green)
|
||||||
|
{
|
||||||
|
set_output(UI_V1_TOP_LED_RED, red);
|
||||||
|
set_output(UI_V1_TOP_LED_GREEN, green);
|
||||||
|
|
||||||
|
(void)i2c_write(CONFIG_UI_V1_I2C_ADDR, PCA9539_OUT_REG, 1, out_reg, 2);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void v1_set_bottom_leds(int red, int green)
|
||||||
|
{
|
||||||
|
set_output(UI_V1_BOTTOM_LED_RED, red);
|
||||||
|
set_output(UI_V1_BOTTOM_LED_GREEN, green);
|
||||||
|
|
||||||
|
(void)i2c_write(CONFIG_UI_V1_I2C_ADDR, PCA9539_OUT_REG, 1, out_reg, 2);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void v2_set_top_leds(int red, int green)
|
||||||
|
{
|
||||||
|
set_output(UI_V2_TOP_LED_RED, red);
|
||||||
|
set_output(UI_V2_TOP_LED_GREEN, green);
|
||||||
|
|
||||||
|
(void)i2c_write(CONFIG_UI_V2_I2C_ADDR, PCA9538_OUT_REG, 1, out_reg, 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void v2_set_bottom_leds(int red, int green)
|
||||||
|
{
|
||||||
|
set_output(UI_V2_BOTTOM_LED_RED, red);
|
||||||
|
set_output(UI_V2_BOTTOM_LED_GREEN, green);
|
||||||
|
|
||||||
|
(void)i2c_write(CONFIG_UI_V2_I2C_ADDR, PCA9538_OUT_REG, 1, out_reg, 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void ui_init(int i2c_bus)
|
||||||
|
{
|
||||||
|
int bus = -1;
|
||||||
|
int claimed;
|
||||||
|
|
||||||
|
ioext_i2c_bus = i2c_bus;
|
||||||
|
|
||||||
|
claimed = switch_i2c_bus(&bus);
|
||||||
|
if (claimed == 0) {
|
||||||
|
detect_version();
|
||||||
|
init_io();
|
||||||
|
}
|
||||||
|
revert_i2c_bus(bus);
|
||||||
|
}
|
||||||
|
|
||||||
|
int ui_version(void)
|
||||||
|
{
|
||||||
|
return hw_version;
|
||||||
|
}
|
||||||
|
|
||||||
|
void ui_set_top_led(int red, int green)
|
||||||
|
{
|
||||||
|
int bus = -1;
|
||||||
|
int claimed;
|
||||||
|
|
||||||
|
claimed = switch_i2c_bus(&bus);
|
||||||
|
if (claimed == 0) {
|
||||||
|
switch (hw_version) {
|
||||||
|
case 1: v1_set_top_leds(red, green); break;
|
||||||
|
case 2: v2_set_top_leds(red, green); break;
|
||||||
|
default: break;
|
||||||
|
}
|
||||||
|
revert_i2c_bus(bus);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void ui_set_bottom_led(int red, int green)
|
||||||
|
{
|
||||||
|
int bus = -1;
|
||||||
|
int claimed;
|
||||||
|
|
||||||
|
claimed = switch_i2c_bus(&bus);
|
||||||
|
if (claimed == 0) {
|
||||||
|
switch (hw_version) {
|
||||||
|
case 1: v1_set_bottom_leds(red, green); break;
|
||||||
|
case 2: v2_set_bottom_leds(red, green); break;
|
||||||
|
default: break;
|
||||||
|
}
|
||||||
|
revert_i2c_bus(bus);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -13,16 +13,27 @@
|
||||||
|
|
||||||
|
|
||||||
#define CONFIG_UI_I2C_BUS 1
|
#define CONFIG_UI_I2C_BUS 1
|
||||||
#define CONFIG_UI_I2C_ADDR 0x74 /* Pages 0 and 1, Pages 2 and 3 -> 0x59 */
|
|
||||||
|
|
||||||
#define CONFIG_UIV2_I2C_ADDR 0x70 /* Pages 0 and 1, Pages 2 and 3 -> 0x59 */
|
#define CONFIG_UI_V1_I2C_ADDR 0x74
|
||||||
|
#define CONFIG_UI_V2_I2C_ADDR 0x70
|
||||||
|
|
||||||
extern void ui_i2c_init(int i2c_bus);
|
|
||||||
|
|
||||||
extern int ui_claim_i2c_bus(int* old_bus);
|
/**
|
||||||
extern int ui_release_i2c_bus(int bus);
|
* Initializes user interface module.
|
||||||
|
*
|
||||||
|
* @param i2c_bus Number of I2C bus UI is attached to.
|
||||||
|
*/
|
||||||
|
extern void ui_init(int i2c_bus);
|
||||||
|
|
||||||
extern int detect_ui(void);
|
/**
|
||||||
|
* Returns hardware version of UI.
|
||||||
|
*
|
||||||
|
* @return 0: No or unknown UI
|
||||||
|
* >0: Version (e.g. 1 or 2)
|
||||||
|
*/
|
||||||
|
extern int ui_version(void);
|
||||||
|
|
||||||
|
void ui_set_top_led(int red, int green);
|
||||||
|
void ui_set_bottom_led(int red, int green);
|
||||||
|
|
||||||
#endif /* UI_H */
|
#endif /* UI_H */
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue