nmhw21: prepare UI v2.0 implementation
This commit is contained in:
parent
c0550c87fb
commit
a962411cbf
|
|
@ -14,11 +14,52 @@
|
|||
|
||||
#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;
|
||||
static int ui_bus_claimed = false;
|
||||
/* HW V2.0: PCA9538ABS (8 Bit) */
|
||||
#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)
|
||||
{
|
||||
int ret = 0;
|
||||
|
|
@ -27,92 +68,152 @@ static int switch_i2c_bus(int* old_bus)
|
|||
return -1;
|
||||
|
||||
*old_bus = i2c_get_bus_num();
|
||||
if (*old_bus != ui_i2c_bus) {
|
||||
ret = i2c_set_bus_num(ui_i2c_bus);
|
||||
if (*old_bus != ioext_i2c_bus) {
|
||||
ret = i2c_set_bus_num(ioext_i2c_bus);
|
||||
}
|
||||
|
||||
ui_bus_claimed = true;
|
||||
bus_claimed++;
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int revert_i2c_bus(int bus)
|
||||
static void revert_i2c_bus(int bus)
|
||||
{
|
||||
int ret = 0;
|
||||
if (ui_i2c_bus != bus) {
|
||||
ret = i2c_set_bus_num(bus);
|
||||
if (ioext_i2c_bus != bus) {
|
||||
(void)i2c_set_bus_num(bus);
|
||||
}
|
||||
|
||||
ui_bus_claimed = false;
|
||||
return ret;
|
||||
bus_claimed--;
|
||||
}
|
||||
|
||||
|
||||
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)
|
||||
static void detect_version(void)
|
||||
{
|
||||
int ret;
|
||||
u8 temp;
|
||||
uint8_t temp = 0;
|
||||
|
||||
/* Argument check */
|
||||
if ((reg >= 8)) {
|
||||
return -1;
|
||||
hw_version = 0;
|
||||
|
||||
/* 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 (ui_bus_claimed == false) {
|
||||
return -2;
|
||||
if (hw_version == 0) {
|
||||
/* Try to detect PCA9538 on V2.x HW */
|
||||
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 */
|
||||
int detect_ui(void)
|
||||
static void init_io(void)
|
||||
{
|
||||
int bus;
|
||||
int claim;
|
||||
uint8_t val;
|
||||
static int ui_detected = -1; /* -1: unitialized, 0: UI not available, 1: UI V1 detected ,2: UI V2 detected */
|
||||
if (ui_detected < 0) {
|
||||
claim = ui_claim_i2c_bus(&bus);
|
||||
if (claim == 0) {
|
||||
if ( 0 == ui_i2c_get_reg(0x00, &val,1))
|
||||
ui_detected = 1;
|
||||
else {
|
||||
if ( 0 == ui_i2c_get_reg(0x00, &val,2))
|
||||
ui_detected = 2;
|
||||
else
|
||||
ui_detected = 0;
|
||||
switch (hw_version) {
|
||||
case 1: {
|
||||
uint8_t dir[2] = { 0x00, 0x00 }; /* All IOs = Outputs */
|
||||
(void)i2c_write(CONFIG_UI_V1_I2C_ADDR, PCA9539_CONF_REG, 1, dir, 2);
|
||||
|
||||
out_reg[0] = 0xFF;
|
||||
out_reg[1] = 0xFF;
|
||||
break;
|
||||
}
|
||||
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_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 */
|
||||
|
|
|
|||
Loading…
Reference in New Issue