diff --git a/firmware/ec/src/Devices/ocmp_wrappers/ocmp_adt7481.c b/firmware/ec/src/Devices/ocmp_wrappers/ocmp_adt7481.c new file mode 100644 index 0000000000..58aad286cd --- /dev/null +++ b/firmware/ec/src/Devices/ocmp_wrappers/ocmp_adt7481.c @@ -0,0 +1,132 @@ +/** +* Copyright (c) 2017-present, Facebook, Inc. +* All rights reserved. +* +* This source code is licensed under the BSD-style license found in the +* LICENSE file in the root directory of this source tree. An additional grant +* of patent rights can be found in the PATENTS file in the same directory. +*/ +#include "common/inc/ocmp_wrappers/ocmp_adt7481.h" + +#include "helpers/array.h" +#include "inc/devices/adt7481.h" + +typedef enum Adt7481Status { + ADT7481_STATUS_TEMPERATURE = 0, +} Adt7481Status; + +typedef enum Adt7481SConfig { + ADT7481_CONFIG_LIM_LOW = 0, + ADT7481_CONFIG_LIM_HIGH, + ADT7481_CONFIG_LIM_CRIT, +} Adt7481SConfig; + +typedef enum Adt7481SAlert { + ADT7481_ALERT_LOW = 0, + ADT7481_ALERT_HIGH, + ADT7481_ALERT_CRITICAL +} Adt7481SAlert; + +static bool _get_status(void *driver, unsigned int param_id, + void *return_buf) { + switch (param_id) { + case ADT7481_STATUS_TEMPERATURE: { + int8_t *res = return_buf; + if (adt7481_get_remote2_temp_val(driver, res) == RETURN_OK) { + return true; + } + break; + } + default: + LOGGER_ERROR("ADT7481::Unknown status param %d\n", param_id); + return false; + } + return false; +} + +static bool _get_config(void *driver, unsigned int param_id, + void *return_buf) { + switch (param_id) { + case ADT7481_CONFIG_LIM_LOW: + case ADT7481_CONFIG_LIM_HIGH: + case ADT7481_CONFIG_LIM_CRIT: { + int8_t *res = return_buf; + if (adt7481_get_remote2_temp_limit(driver, param_id + 1, res) + == RETURN_OK) { + return true; + } + break; + } + default: + LOGGER_ERROR("ADT7481::Unknown config param %d\n", param_id); + return false; + } + return false; +} + +static bool _set_config(void *driver, unsigned int param_id, + const void *data) { + switch (param_id) { + case ADT7481_CONFIG_LIM_LOW: + case ADT7481_CONFIG_LIM_HIGH: + case ADT7481_CONFIG_LIM_CRIT: { + const int8_t *limit = data; + if (adt7481_set_remote2_temp_limit(driver, param_id + 1, *limit) + == RETURN_OK) { + return true; + } + break; + } + default: + LOGGER_ERROR("ADT7481::Unknown config param %d\n", param_id); + return false; + } + return false; +} + +static ePostCode _probe(void *driver, POSTData *postData) +{ + return adt7481_probe(driver,postData); +} + +static ePostCode _init(void *driver, const void *config, + const void *alert_token) +{ + const ADT7481_Config *adt7481_config = config; + if (adt7481_config == NULL) { + return POST_DEV_CFG_FAIL; + } + for (int i = 0; i < ARRAY_SIZE(adt7481_config->limits); ++i) { + if (adt7481_set_local_temp_limit( + driver, i + 1, adt7481_config->limits[i]) != RETURN_OK || + adt7481_set_remote1_temp_limit( + driver, i + 1, adt7481_config->limits[i]) != RETURN_OK || + adt7481_set_remote2_temp_limit( + driver, i + 1, adt7481_config->limits[i]) != RETURN_OK) { + return POST_DEV_CFG_FAIL; + } + } + + if (adt7481_set_config1(driver, ADT7481_CONFIGURATION_REG_VALUE) + != RETURN_OK) { + return POST_DEV_CFG_FAIL; + } + + if (adt7481_set_conv_rate(driver, ADT7481_CONVERSION_RATE_REG_VALUE) + != RETURN_OK) { + return POST_DEV_CFG_FAIL; + } + + return POST_DEV_CFG_DONE; +} + +/* TODO: dedup with SE98A driver */ +/* TODO: enable alerts (requires major ADT driver changes) */ +const Driver_fxnTable ADT7481_fxnTable = { + /* Message handlers */ + .cb_probe = _probe, + .cb_init = _init, + .cb_get_status = _get_status, + .cb_get_config = _get_config, + .cb_set_config = _set_config, +}; diff --git a/firmware/ec/src/Devices/ocmp_wrappers/ocmp_cat24c04.c b/firmware/ec/src/Devices/ocmp_wrappers/ocmp_cat24c04.c new file mode 100644 index 0000000000..68609e885e --- /dev/null +++ b/firmware/ec/src/Devices/ocmp_wrappers/ocmp_cat24c04.c @@ -0,0 +1,159 @@ +/** + * Copyright (c) 2017-present, Facebook, Inc. + * All rights reserved. + * + * This source code is licensed under the BSD-style license found in the + * LICENSE file in the root directory of this source tree. An additional grant + * of patent rights can be found in the PATENTS file in the same directory. + */ +#include "common/inc/ocmp_wrappers/ocmp_eeprom_cat24c04.h" + +#include "common/inc/global/Framework.h" +#include "inc/common/global_header.h" +#include "inc/devices/eeprom.h" + +#include + +static bool _sid_get_status_parameters_data(void *driver, + unsigned int param, + void *data); +/***************************************************************************** + ** FUNCTION NAME : _sid_get_status_parameters_data + ** + ** DESCRIPTION : Reading Serial Id's from the GBC EEPROM. + ** + ** ARGUMENTS : Pointer to OCMPMessageFrame structure + ** + ** RETURN TYPE : Success or Failure + ** + *****************************************************************************/ +static bool _sid_get_status_parameters_data(void *driver, + unsigned int param, + void *data) +{ + const eOCStatusParamId paramIndex = (eOCStatusParamId)param; + const Eeprom_Cfg *cfg = ( Eeprom_Cfg*)driver; + ReturnStatus status = RETURN_OK; + switch (paramIndex) { + case OC_STAT_SYS_SERIAL_ID: + { + memset(data, '\0', OC_CONNECT1_SERIAL_SIZE + 1); + status = eeprom_read_oc_info(data); + LOGGER_DEBUG("SYS:INFO:::: OC Connect1 serial id %s.\n", + data); + break; + } + case OC_STAT_SYS_GBC_BOARD_ID: + { + memset(data, '\0', OC_GBC_BOARD_INFO_SIZE + 1); + status = eeprom_read_board_info(cfg, data); + LOGGER_DEBUG("SYS:INFO:::: OC Connect1 GBC board is %s.\n", + data); + break; + } + default: + { + status = RETURN_NOTOK; + } + } + return (status == RETURN_OK); +} + +/***************************************************************************** + ** FUNCTION NAME : Sdr_InventoryGetStatus + ** + ** DESCRIPTION : Reading Serial Id's from the SDR EEPROM. + ** + ** ARGUMENTS : Pointer to OCMPMessageFrame structure + ** + ** RETURN TYPE : Success or Failure + ** + *****************************************************************************/ +bool Sdr_InventoryGetStatus(void *driver, unsigned int param_id, + void *return_buf) { + const Eeprom_Cfg *cfg = ( Eeprom_Cfg*)driver; + switch (param_id) { + case 0: /* TODO: gross magic number */ + memset(return_buf,'\0', OC_SDR_BOARD_INFO_SIZE + 1); + if (eeprom_read_board_info(cfg, return_buf) == RETURN_OK) { + return true; + } + LOGGER_DEBUG("SDR:INFO:: Board id: %s\n", return_buf); + break; + default: + LOGGER_ERROR("SDR:ERROR::Unknown param %u\n", param_id); + break; + } + return false; +} +/***************************************************************************** + ** FUNCTION NAME : RFFE_InventoryGetStatus + ** + ** DESCRIPTION : Reading Serial Id's from the RFFE EEPROM. + ** + ** ARGUMENTS : Pointer to OCMPMessageFrame structure + ** + ** RETURN TYPE : Success or Failure + ** + *****************************************************************************/ +bool RFFE_InventoryGetStatus(void *driver, unsigned int param_id, + void *return_buf) { + const Eeprom_Cfg *cfg = (Eeprom_Cfg *)driver; + switch (param_id) { + case 0: /* TODO: gross magic number */ + memset(return_buf, '\0', OC_RFFE_BOARD_INFO_SIZE + 1); + if (eeprom_read_board_info(cfg, return_buf) + == RETURN_OK) { + return true; + } + LOGGER_DEBUG("RFFE:INFO:: Board id: %s\n", return_buf); + break; + default: + LOGGER_ERROR("RFFE:ERROR::Unknown param %u\n", param_id); + break; + } + return false; +} + +static ePostCode _init_eeprom(void *driver, const void **config, + const void *alert_token) +{ + Eeprom_Cfg *eeprom = (Eeprom_Cfg *)driver; + uint8_t write = 0x01; + uint8_t read = 0x00; + + eeprom_init(eeprom); + eeprom_enable_write(eeprom); + eeprom_write(eeprom, OC_TEST_ADDRESS, &write, 1); + NOP_DELAY(); /* TODO: the eeprom driver should handle this */ + eeprom_disable_write(eeprom); + eeprom_read(eeprom, OC_TEST_ADDRESS, &read, 1); + + if (write == read) { + return POST_DEV_CFG_DONE; + } + return POST_DEV_CFG_FAIL; +} + +const Driver_fxnTable CAT24C04_gbc_sid_fxnTable = { + /* Message handlers */ + .cb_init = _init_eeprom, + .cb_get_status = _sid_get_status_parameters_data, +}; + +const Driver_fxnTable CAT24C04_gbc_inv_fxnTable= { + .cb_init = _init_eeprom, +}; + +const Driver_fxnTable CAT24C04_sdr_inv_fxnTable = { + /* Message handlers */ + .cb_init = _init_eeprom, + .cb_get_status = Sdr_InventoryGetStatus, +}; + +const Driver_fxnTable CAT24C04_fe_inv_fxnTable = { + /* Message handlers */ + .cb_init = _init_eeprom, + .cb_get_status = RFFE_InventoryGetStatus, +}; + diff --git a/firmware/ec/src/Devices/ocmp_wrappers/ocmp_dat-xxr5a-pp.c b/firmware/ec/src/Devices/ocmp_wrappers/ocmp_dat-xxr5a-pp.c new file mode 100644 index 0000000000..e9826ae1ed --- /dev/null +++ b/firmware/ec/src/Devices/ocmp_wrappers/ocmp_dat-xxr5a-pp.c @@ -0,0 +1,149 @@ +/** + * Copyright (c) 2017-present, Facebook, Inc. + * All rights reserved. + * + * This source code is licensed under the BSD-style license found in the + * LICENSE file in the root directory of this source tree. An additional grant + * of patent rights can be found in the PATENTS file in the same directory. + */ +#include "common/inc/ocmp_wrappers/ocmp_dat-xxr5a-pp.h" + +#include "common/inc/global/Framework.h" +#include "drivers/PinGroup.h" +#include "helpers/math.h" +#include "inc/subsystem/rffe/rffe.h" +#include "inc/common/global_header.h" +#include "inc/devices/dat-xxr5a-pp.h" + +#include + +typedef enum DatConfig { + DAT_CONFIG_ATTENUATION = 0, +} DatConfig; + +static bool _get_config(void *driver, unsigned int param_id, + void *return_buf) { + bool ret = false; + switch (param_id) { + case DAT_CONFIG_ATTENUATION: { + DATR5APP_Cfg *cfg = driver; + uint8_t atten; + const PinGroup pin_group = { + .num_pin = DATR5APP_PIN_COUNT, + .pins = cfg->pin_group + }; + if (PinGroup_read(&pin_group, &atten) != RETURN_OK) { + ret = false; + } else { + LOGGER_DEBUG("DAT-XXR5A-PP+:DEBUG:: Attenuation is %.1f\n", + (atten / 2.0)); + *(int16_t *)return_buf = atten; + ret = true; + } + break; + } + default: { + LOGGER_ERROR("DAT-XXR5A-PP+::Unknown config param %d\n", param_id); + ret = false; + } + } + return ret; +} + +static bool _set_attenuation(void *driver, int16_t atten) +{ + DATR5APP_Cfg *cfg = driver; + + /* TODO: no idea why we accept negative numbers */ + if (cfg->pin_16db.port) { + atten = CONSTRAIN(atten, 0, (31.5 * 2)); + } else { + atten = CONSTRAIN(atten, 0, (15.5 * 2)); + } + + /* Disable input latch */ + OcGpio_write(&cfg->pin_le, false); + /* Attenuation enable */ + // OcGpio_write(&cfg->pin_tx_attn_enb, true); + + /* Set the attenuation value */ + /* TODO: value is provided as x2, so 0.5 value is bit 0, consider + * changing, at least on CLI to more intuitive interface */ + const PinGroup pin_group = { + .num_pin = DATR5APP_PIN_COUNT, + .pins = cfg->pin_group + }; + + if (PinGroup_write(&pin_group, atten) != RETURN_OK) { + return false; + } + + /* Latch the input (tPDSUP, tLEPW, tPDHLD are all 10ns, so we can + * sleep for 1ms, giving us more than enough time to latch) */ + Task_sleep(1); + OcGpio_write(&cfg->pin_le, true); + Task_sleep(1); + OcGpio_write(&cfg->pin_le, false); + Task_sleep(1); + return true; +} + +static bool _set_config(void *driver, unsigned int param_id, + const void *data) { + switch (param_id) { + case DAT_CONFIG_ATTENUATION: { + return _set_attenuation(driver, *(int16_t *)data); + } + default: + LOGGER_ERROR("DAT-XXR5A-PP+::Unknown config param %d\n", param_id); + return false; + } +} + +static ePostCode _probe(void *driver) +{ + /* TODO: perhaps GPIO should provide probe/test function? for now we'll + * assume that reading from the pin will tell us if the pin is working */ + DATR5APP_Cfg *cfg = driver; + uint8_t atten; + const PinGroup pin_group = { + .num_pin = DATR5APP_PIN_COUNT, + .pins = cfg->pin_group + }; + if (PinGroup_read(&pin_group, &atten) != RETURN_OK) { + return POST_DEV_MISSING; + } + + return POST_DEV_FOUND; +} + +static ePostCode _init(void *driver, const void *config, + const void *alert_token) +{ + DATR5APP_Cfg *cfg = (DATR5APP_Cfg *)driver; + DATR5APP_Config *cfg_atten = (DATR5APP_Config *)config; + PinGroup pin_group = { + .num_pin = DATR5APP_PIN_COUNT, + .pins = cfg->pin_group + }; + if (OcGpio_configure(&cfg->pin_le, OCGPIO_CFG_OUTPUT) < OCGPIO_SUCCESS) { + return POST_DEV_CFG_FAIL; + } + if (PinGroup_configure(&pin_group, OCGPIO_CFG_OUTPUT | OCGPIO_CFG_OUT_HIGH) + != RETURN_OK) { + return POST_DEV_CFG_FAIL; + } + + /* Set default attenuation */ + _set_attenuation(driver, cfg_atten->attenuation); + return POST_DEV_CFG_DONE; +} + +const Driver_fxnTable DATXXR5APP_fxnTable = { + /* Message handlers */ + .cb_probe = _probe, + .cb_init = _init, + .cb_get_status = NULL, + .cb_get_config = _get_config, + .cb_set_config = _set_config, +}; diff --git a/firmware/ec/src/Devices/ocmp_wrappers/ocmp_debugi2c.c b/firmware/ec/src/Devices/ocmp_wrappers/ocmp_debugi2c.c new file mode 100644 index 0000000000..3313e335bb --- /dev/null +++ b/firmware/ec/src/Devices/ocmp_wrappers/ocmp_debugi2c.c @@ -0,0 +1,34 @@ +/** + * Copyright (c) 2017-present, Facebook, Inc. + * All rights reserved. + * + * This source code is licensed under the BSD-style license found in the + * LICENSE file in the root directory of this source tree. An additional grant + * of patent rights can be found in the PATENTS file in the same directory. + */ +#include "inc/ocmp_wrappers/ocmp_debugi2c.h" + +#include "common/inc/global/ocmp_frame.h" +#include "common/inc/global/Framework.h" +#include "inc/common/global_header.h" +#include "inc/common/i2cbus.h" +#include "inc/devices/debug_oci2c.h" + +/* TI-RTOS driver files */ +#include + +bool i2c_read(void* i2c_cfg, void *oci2c ) +{ + S_I2C_Cfg* s_oc_i2c_cfg = (S_I2C_Cfg*)i2c_cfg; + S_OCI2C* s_oci2c = (S_OCI2C*)oci2c; + I2C_Handle i2cHandle = i2c_open_bus(s_oc_i2c_cfg->bus); + return (i2c_reg_read_32bit_address(i2cHandle, s_oci2c->slaveAddress, s_oci2c->reg_address, &s_oci2c->reg_value, s_oci2c->number_of_bytes, s_oci2c->write_count) == RETURN_OK); +} + +bool i2c_write(void* i2c_cfg, void *oci2c ) +{ + S_I2C_Cfg* s_oc_i2c_cfg = (S_I2C_Cfg*)i2c_cfg; + S_OCI2C* s_oci2c = (S_OCI2C*)oci2c; + I2C_Handle i2cHandle = i2c_open_bus(s_oc_i2c_cfg->bus); + return (i2c_reg_write_32bit_address(i2cHandle, s_oci2c->slaveAddress, s_oci2c->reg_address, s_oci2c->reg_value, s_oci2c->number_of_bytes, s_oci2c->write_count) == RETURN_OK); +} diff --git a/firmware/ec/src/Devices/ocmp_wrappers/ocmp_debugmdio.c b/firmware/ec/src/Devices/ocmp_wrappers/ocmp_debugmdio.c new file mode 100644 index 0000000000..b92595ed2e --- /dev/null +++ b/firmware/ec/src/Devices/ocmp_wrappers/ocmp_debugmdio.c @@ -0,0 +1,76 @@ +/** + * Copyright (c) 2018-present, Facebook, Inc. + * All rights reserved. + * + * This source code is licensed under the BSD-style license found in the + * LICENSE file in the root directory of this source tree. An additional grant + * of patent rights can be found in the PATENTS file in the same directory. + */ +#include "inc/ocmp_wrappers/ocmp_debugmdio.h" + +#include "common/inc/global/ocmp_frame.h" +#include "common/inc/global/Framework.h" +#include "inc/common/global_header.h" +#include "inc/devices/88E6071_registers.h" +#include "inc/devices/debug_ocmdio.h" + +#include "inc/devices/mdio_bb.h" + +#define CLAUSE_45_REQUEST(reg_address) check_clause_45(s_ocmdio->reg_address) +#define PORT_REG_REQUEST(port) check_clause_22(s_oc_mdio_cfg->port) +#define PHY_PORT_MAX 5 + +bool check_clause_45(uint16_t regAddr) { + bool status = false; + if (REG_C45_PACKET_GEN == regAddr || REG_C45_CRC_ERROR_COUNTER == regAddr) + status = true; + return status; +} + +bool check_clause_22(uint8_t port) { + bool status = false; + if (port < PHY_PORT_MAX) + status = true; + return status; +} + +bool mdio_read(void* mdio_cfg, void *ocmdio ) +{ + S_MDIO_Cfg* s_oc_mdio_cfg = (S_MDIO_Cfg*)mdio_cfg; + S_OCMDIO* s_ocmdio = (S_OCMDIO*)ocmdio; + s_ocmdio->reg_value= 0xf00f; + + if (CLAUSE_45_REQUEST(reg_address)) + /*PHY registers use Reg 13 and Reg 14 as paging mechanism to access Clause 45 registers*/ + s_ocmdio->reg_value = mdiobb_read_by_paging_c45(s_oc_mdio_cfg->port, s_ocmdio->reg_address); + else if (PORT_REG_REQUEST(port)) + /*PHY registers use Reg 13 and Reg 14 as paging mechanism to access Clause 22 registers*/ + s_ocmdio->reg_value = mdiobb_read_by_paging(s_oc_mdio_cfg->port, s_ocmdio->reg_address); + else + /*GLOBAL and SWITCH registers can be accessed directly*/ + s_ocmdio->reg_value = mdiobb_read(s_oc_mdio_cfg->port, s_ocmdio->reg_address); + return 0; +} + +bool mdio_write(void* mdio_cfg, void *ocmdio ) +{ + S_MDIO_Cfg* s_oc_mdio_cfg = (S_MDIO_Cfg*)mdio_cfg; + S_OCMDIO* s_ocmdio = (S_OCMDIO*)ocmdio; + + if (CLAUSE_45_REQUEST(reg_address)) { + /*PHY registers use Reg 13 and Reg 14 as paging mechanism to access Clause 45 registers*/ + mdiobb_write_by_paging_c45(s_oc_mdio_cfg->port, s_ocmdio->reg_address, s_ocmdio->reg_value); + s_ocmdio->reg_value = mdiobb_read_by_paging_c45(s_oc_mdio_cfg->port, s_ocmdio->reg_address); + } + else if (PORT_REG_REQUEST(port)) { + /*PHY registers use Reg 13 and Reg 14 as paging mechanism to access Clause 22 registers*/ + mdiobb_write_by_paging(s_oc_mdio_cfg->port, s_ocmdio->reg_address, s_ocmdio->reg_value); + s_ocmdio->reg_value = mdiobb_read_by_paging(s_oc_mdio_cfg->port, s_ocmdio->reg_address); + } + else { + /*GLOBAL and SWITCH registers can be accessed directly*/ + mdiobb_write(s_oc_mdio_cfg->port, s_ocmdio->reg_address, s_ocmdio->reg_value); + s_ocmdio->reg_value = mdiobb_read(s_oc_mdio_cfg->port, s_ocmdio->reg_address); + } + return 0; +} diff --git a/firmware/ec/src/Devices/ocmp_wrappers/ocmp_debugocgpio.c b/firmware/ec/src/Devices/ocmp_wrappers/ocmp_debugocgpio.c new file mode 100644 index 0000000000..4015186273 --- /dev/null +++ b/firmware/ec/src/Devices/ocmp_wrappers/ocmp_debugocgpio.c @@ -0,0 +1,69 @@ +/** + * Copyright (c) 2017-present, Facebook, Inc. + * All rights reserved. + * + * This source code is licensed under the BSD-style license found in the + * LICENSE file in the root directory of this source tree. An additional grant + * of patent rights can be found in the PATENTS file in the same directory. + */ +#include "inc/ocmp_wrappers/ocmp_debugocgpio.h" + +#include "common/inc/global/Framework.h" +#include "common/inc/global/ocmp_frame.h" +#include "inc/common/global_header.h" +#include "inc/devices/debug_ocgpio.h" + + +#include + +#define NO_GPIO_PINS_IN_GROUP 8 +extern GPIO_PinConfig gpioPinConfigs[]; + +bool ocgpio_set(void* gpio_cfg, void* oc_gpio ) +{ + S_OCGPIO_Cfg* oc_gpio_cfg = (S_OCGPIO_Cfg*)gpio_cfg; + S_OCGPIO* s_oc_gpio = (S_OCGPIO*)oc_gpio; + int ret = 0; + uint8_t idx = ((oc_gpio_cfg->group != 0)?(((oc_gpio_cfg->group-1) * NO_GPIO_PINS_IN_GROUP) + s_oc_gpio->pin):s_oc_gpio->pin); + OcGpio_Pin ocgpio = { (oc_gpio_cfg->port), idx, ((oc_gpio_cfg->group != 0)?(gpioPinConfigs[idx]>>16):OCGPIO_CFG_OUT_STD)}; + ret = OcGpio_configure(&ocgpio, OCGPIO_CFG_OUTPUT); + ret = OcGpio_write(&ocgpio,s_oc_gpio->value); + return (ret == 0); +} + +bool ocgpio_get(void* gpio_cfg, void* oc_gpio ) +{ + S_OCGPIO_Cfg* oc_gpio_cfg = (S_OCGPIO_Cfg*)gpio_cfg; + S_OCGPIO* s_oc_gpio = (S_OCGPIO*)oc_gpio; + int ret = 0; + uint8_t idx = ((oc_gpio_cfg->group != 0)?(((oc_gpio_cfg->group-1) * NO_GPIO_PINS_IN_GROUP) + s_oc_gpio->pin):s_oc_gpio->pin); + OcGpio_Pin ocgpio = { (oc_gpio_cfg->port), idx, ((oc_gpio_cfg->group!= 0)?(gpioPinConfigs[idx]>>16):OCGPIO_CFG_IN_PU)}; + ret = OcGpio_configure(&ocgpio, OCGPIO_CFG_INPUT); + s_oc_gpio->value = OcGpio_read(&ocgpio); + if ( s_oc_gpio->value < 0) { + ret = -1; + } + return (ret == 0); +} + +static ePostCode _probe(S_OCGPIO_Cfg* oc_gpio_cfg) +{ + if (OcGpio_probe(oc_gpio_cfg->port) != 0) { + return POST_DEV_MISSING; + } else { + return POST_DEV_FOUND; + } +} + +static ePostCode _init(void *driver, const void *config, + const void *alert_token) +{ + //Dummy functions. + return POST_DEV_CFG_DONE; +} + +const Driver_fxnTable DEBUG_OCGPIO_fxnTable = { + /* Message handlers */ + .cb_probe = _probe, + .cb_init = _init, +}; diff --git a/firmware/ec/src/Devices/ocmp_wrappers/ocmp_eth_sw.c b/firmware/ec/src/Devices/ocmp_wrappers/ocmp_eth_sw.c new file mode 100644 index 0000000000..e68697abae --- /dev/null +++ b/firmware/ec/src/Devices/ocmp_wrappers/ocmp_eth_sw.c @@ -0,0 +1,186 @@ +/** + * Copyright (c) 2017-present, Facebook, Inc. + * All rights reserved. + * + * This source code is licensed under the BSD-style license found in the + * LICENSE file in the root directory of this source tree. An additional grant + * of patent rights can be found in the PATENTS file in the same directory. + */ +#include "common/inc/ocmp_wrappers/ocmp_eth_sw.h" + +#include "common/inc/global/Framework.h" +#include "inc/devices/eth_sw.h" + +bool ETHERNET_reset(void *driver, void *params) +{ + ReturnStatus status = RETURN_OK; + status = eth_sw_set_config_soft_reset(driver); + return status; +} + +static bool _get_status(void *driver, unsigned int param_id, + void *return_buf) +{ + Eth_cfg *cfg = (Eth_cfg*)driver; + switch (param_id) { + case ETH_SW_STATUS_SPEED: { + uint8_t *res = return_buf; + return (eth_sw_get_status_speed(driver, cfg->eth_sw_port, res) == RETURN_OK); + } + case ETH_SW_STATUS_DUPLEX: { + uint8_t *res = return_buf; + return (eth_sw_get_status_duplex(driver, cfg->eth_sw_port, res) == RETURN_OK); + } + case ETH_SW_STATUS_AUTONEG_ON: { + uint8_t *res = return_buf; + return (eth_sw_get_status_auto_neg(driver, cfg->eth_sw_port, res) == RETURN_OK); + } + case ETH_SW_STATUS_POWER_DOWN_MODE_EN: { + uint8_t *res = return_buf; + return (eth_sw_get_status_power_down_mode(driver, cfg->eth_sw_port, res) == RETURN_OK); + } + case ETH_SW_STATUS_AUTONEG_COMPLETE: { + uint8_t *res = return_buf; + return (eth_sw_get_status_auto_neg_complete(driver, cfg->eth_sw_port, res) == RETURN_OK); + } + case ETH_SW_STATUS_LINK: { + uint8_t *res = return_buf; + return (eth_sw_get_status_link_up(driver, cfg->eth_sw_port, res) == RETURN_OK); + } + default: + LOGGER_ERROR("ETH_SW::Unknown status param %d\n", param_id); + return false; + } +} + +static bool _get_config(void *driver, unsigned int param_id, + void *return_buf) +{ + Eth_cfg *cfg = (Eth_cfg*)driver; + switch (param_id) { + case ETH_SW_CONFIG_SPEED: { + uint8_t *res = return_buf; + return (eth_sw_get_config_speed(driver, cfg->eth_sw_port, res) + == RETURN_OK); + } + case ETH_SW_CONFIG_DUPLEX: { + uint8_t *res = return_buf; + return (eth_sw_get_config_duplex(driver, cfg->eth_sw_port, res) + == RETURN_OK); + } + case ETH_SW_CONFIG_POWER_DOWN: { + uint8_t *res = return_buf; + return (eth_sw_get_config_power_down(driver, cfg->eth_sw_port, res) + == RETURN_OK); + } + case ETH_SW_CONFIG_INTERRUPT_EN: { + uint8_t *res = return_buf; + return (eth_sw_get_config_interrupt_enable(driver, cfg->eth_sw_port, res) + == RETURN_OK); + } + case ETH_SW_CONFIG_SW_RESET: { + uint8_t *res = return_buf; + *res = 0; /*0x0003*/ + return RETURN_OK; + } + case ETH_SW_CONFIG_RESTART_AUTONEG: { + uint8_t *res = return_buf; + *res = 0; /*0xN100*/ + return RETURN_OK; + } + default: + LOGGER_ERROR("ETH_SW::Unknown config param %d\n", param_id); + return false; + } +} + +static bool _set_config(void *driver, unsigned int param_id, + const void *data) +{ + Eth_cfg *cfg = (Eth_cfg*)driver; + switch (param_id) { + case ETH_SW_CONFIG_SPEED: { + uint8_t *res = (uint8_t*)data; + return (eth_sw_set_config_speed(driver, cfg->eth_sw_port, *res) + == RETURN_OK); + } + case ETH_SW_CONFIG_DUPLEX: { + uint8_t *res = (uint8_t*)data; + return (eth_sw_set_config_duplex(driver, cfg->eth_sw_port, *res) + == RETURN_OK); + } + case ETH_SW_CONFIG_POWER_DOWN: { + uint8_t *res = (uint8_t*)data; + return (eth_sw_set_config_power_down(driver, cfg->eth_sw_port, *res) + == RETURN_OK); + } + case ETH_SW_CONFIG_SW_RESET: { + return (eth_sw_set_config_soft_reset(driver) + == RETURN_OK); + } + case ETH_SW_CONFIG_RESTART_AUTONEG: { + return (eth_sw_set_config_restart_neg(driver, cfg->eth_sw_port) == RETURN_OK); + } + default: + LOGGER_ERROR("ETH_SW::Unknown config param %d\n", param_id); + return false; + } +} + +static ePostCode _probe(void *driver, POSTData *postData) +{ + ePostCode ret = POST_DEV_FOUND; + eth_sw_configure(driver); + ret = eth_sw_probe(driver, postData); + return ret; +} + +static void _alert_handler(Eth_Sw_Events evt, int16_t value, void *alert_data) +{ + unsigned int alert; + switch (evt) { + case ETH_EVT_LINKUP: + alert = ETH_ALERT_LINK_UP; + break; + case ETH_EVT_REMOTEFAULT: + alert = ETH_ALERT_REMOTE_FAULT; + break; + case ETH_EVT_LINKDOWN: + alert = ETH_ALERT_LINK_DOWN; + break; + case ETH_EVT_PARALLELFAULT: + alert = ETH_ALERT_PARALLEL_FAULT; + break; + case ETH_EVT_RECEIVE_ERROR: + alert = ETH_ALERT_RECEIVE_ERROR; + break; + case ETH_EVT_JABBER: + alert = ETH_ALERT_JABBER_DET; + default: + LOGGER_ERROR("ETH_SW::Unknown Ethernet Switch evt: %d\n", evt); + return; + } + OCMP_GenerateAlert(alert_data, alert, &value); + LOGGER_DEBUG("ETH_SW:: Event: %d Value: %d\n", evt, value); +} + +static ePostCode _init(void *driver, const void *config, + const void *alert_token) +{ + ePostCode ret = POST_DEV_CFG_FAIL; + ret = eth_sw_init(driver); + //TODO: Enabling of the ethernet interrupts requires soem more work. + /* + eth_sw_setAlertHandler(driver,_alert_handler,(void *)alert_token); + eth_enable_interrupt();*/ + return ret; +} + +const Driver_fxnTable eth_fxnTable = { + /* Message handlers */ + .cb_probe = _probe, + .cb_init = _init, + .cb_get_status = _get_status, + .cb_get_config = _get_config, + .cb_set_config = _set_config, +}; diff --git a/firmware/ec/src/Devices/ocmp_wrappers/ocmp_fe.c b/firmware/ec/src/Devices/ocmp_wrappers/ocmp_fe.c new file mode 100644 index 0000000000..087f835037 --- /dev/null +++ b/firmware/ec/src/Devices/ocmp_wrappers/ocmp_fe.c @@ -0,0 +1,120 @@ +/** + * Copyright (c) 2017-present, Facebook, Inc. + * All rights reserved. + * + * This source code is licensed under the BSD-style license found in the + * LICENSE file in the root directory of this source tree. An additional grant + * of patent rights can be found in the PATENTS file in the same directory. + */ +#include "common/inc/ocmp_wrappers/ocmp_fe-param.h" + +#include "inc/subsystem/rffe/rffe_ctrl.h" + +static FE_Band_Cfg FE_BandCfg[RFFE_MAX_CHANNEL]; +typedef enum FE_ParamCfg { + FE_CFG_BAND = 0, +} FE_ParamCfg; + +/***************************************************************************** + ** FUNCTION NAME : rffe_ctrl_set_band + ** + ** DESCRIPTION : Set the RF Band. + ** + ** ARGUMENTS : Channel and Band to be read + ** + ** RETURN TYPE : Success or failure + ** + *****************************************************************************/ +bool rffe_ctrl_set_band(rffeChannel channel, rffeBand band) +{ + // TODO: Using RFFE_IO_BOARD_CFG_ADDR we should find Band Config. + FE_BandCfg[channel].band = band; + + DEBUG("RFFECTRL:INFO:: Channel %s RF Band Configuration is %d .\n", + ((channel == 0) ? "1" : "2"), band); + return true; +} + +/***************************************************************************** + ** FUNCTION NAME : rffe_ctrl_get_band + ** + ** DESCRIPTION : Gets the RF Band. + ** + ** ARGUMENTS : Channel and Band to be read + ** + ** RETURN TYPE : Success or failure + ** + *****************************************************************************/ +bool rffe_ctrl_get_band(rffeChannel channel, rffeBand *band) +{ + // TODO: Using RFFE_IO_BOARD_CFG_ADDR we should find Band Config. + *band = FE_BandCfg[channel].band; + + DEBUG("RFFECTRL:INFO:: Channel %s RF Band Configuration is %d .\n", + ((channel == 0) ? "1" : "2"), *band); + return true; +} + +bool static _get_config(void *driver, unsigned int param_id, + void *return_buf) + { + bool ret = false; + FE_Ch_Band_cfg *driverCfg = driver; + switch (param_id) { + case FE_CFG_BAND: + { + ret = rffe_ctrl_get_band(driverCfg->channel,return_buf); + break; + } + default: + { + LOGGER_ERROR("FE_PARAM::Unknown config param %d\n", param_id); + ret = false; + } + } + return ret; +} + +bool static _set_config(void *driver, unsigned int param_id, + void *return_buf) +{ + bool ret = false; + FE_Ch_Band_cfg *driverCfg = driver; + rffeBand *band = (rffeBand*)return_buf; + switch (param_id) { + case FE_CFG_BAND: + { + rffeChannel *cfg = driver; + ret = rffe_ctrl_set_band(driverCfg->channel,*band); + break; + } + default: + { + LOGGER_ERROR("FE_PARAM::Unknown config param %d\n", param_id); + ret = false; + } + } + return ret; +} + +static ePostCode _probe(void *driver) +{ + return POST_DEV_FOUND; +} + +static ePostCode _init(void *driver, const void *config, + const void *alert_token) +{ + FE_Ch_Band_cfg *driverCfg = (FE_Ch_Band_cfg *)driver; + FE_Band_Cfg *cfg = (FE_Band_Cfg *)config; + rffe_ctrl_set_band(driverCfg->channel, cfg->band); + return POST_DEV_FOUND; +} + +const Driver_fxnTable FE_PARAM_fxnTable = { + /* Message handlers */ + .cb_probe = _probe, + .cb_init = _init, + .cb_get_config = _get_config, + .cb_set_config = _set_config, +}; diff --git a/firmware/ec/src/Devices/ocmp_wrappers/ocmp_flash.c b/firmware/ec/src/Devices/ocmp_wrappers/ocmp_flash.c new file mode 100644 index 0000000000..60ec559fdb --- /dev/null +++ b/firmware/ec/src/Devices/ocmp_wrappers/ocmp_flash.c @@ -0,0 +1,75 @@ +/** +* Copyright (c) 2017-present, Facebook, Inc. +* All rights reserved. +* +* This source code is licensed under the BSD-style license found in the +* LICENSE file in the root directory of this source tree. An additional grant +* of patent rights can be found in the PATENTS file in the same directory. +* +*/ + +#include "common/inc/global/Framework.h" +#include "devices/i2c/threaded_int.h" +#include "helpers/memory.h" +#include "inc/devices/AT45DB.h" +#include "inc/common/bigbrother.h" +#include "inc/common/byteorder.h" +#include "inc/common/global_header.h" +#include "inc/utils/ocmp_util.h" + +#define FRAME_SIZE 64 +#define LAST_MSG_FLAG 0 +#define PAYLOAD_SIZE 47 +#define NEXT_MSG_FLAG 1 +#define NEXT_MSG_FLAG_POS 17 + +extern void fileRead(const char *path, UChar *buf, uint32_t size); +uint32_t fileSize(const char *path); + +static bool _read_flash(void *driver, void *buf) +{ + char fileName[] = "logs"; + uint32_t numOfMsg = 0; + uint32_t file_size = 0; + uint8_t *logFile; + + OCMPMessageFrame *tMsg = (OCMPMessageFrame *) OCMP_mallocFrame(PAYLOAD_SIZE); + file_size = fileSize(fileName); + logFile = (uint8_t*)malloc(file_size); + numOfMsg = file_size/FRAME_SIZE; + fileRead(fileName,logFile, file_size); + + while(numOfMsg) + { + logFile[NEXT_MSG_FLAG_POS] = NEXT_MSG_FLAG; + if(numOfMsg == 1){ + logFile[NEXT_MSG_FLAG_POS] = LAST_MSG_FLAG; + } + memcpy(tMsg, logFile, FRAME_SIZE); + Util_enqueueMsg(bigBrotherTxMsgQueue, semBigBrotherMsg, + (uint8_t*)tMsg); + logFile +=FRAME_SIZE; + numOfMsg--; + free(tMsg); + } + free(logFile); + return true; +} + +static ePostCode _init(void *driver, const void *config, + const void *alert_token) +{ + return POST_DEV_CFG_DONE; +} + +static ePostCode _probe(void *driver, POSTData *postData) +{ + return at45db_probe(driver,postData); +} + +const Driver_fxnTable AT45DB641E_fxnTable = { + /* Message handlers */ + .cb_probe = _probe, + .cb_init = _init, + .cb_flash_rw = _read_flash, +}; diff --git a/firmware/ec/src/Devices/ocmp_wrappers/ocmp_ina226.c b/firmware/ec/src/Devices/ocmp_wrappers/ocmp_ina226.c new file mode 100644 index 0000000000..80605227a1 --- /dev/null +++ b/firmware/ec/src/Devices/ocmp_wrappers/ocmp_ina226.c @@ -0,0 +1,126 @@ +/** + * Copyright (c) 2017-present, Facebook, Inc. + * All rights reserved. + * + * This source code is licensed under the BSD-style license found in the + * LICENSE file in the root directory of this source tree. An additional grant + * of patent rights can be found in the PATENTS file in the same directory. + */ +#include "common/inc/ocmp_wrappers/ocmp_ina226.h" + +#include "common/inc/global/Framework.h" +#include "inc/devices/ina226.h" + +typedef enum INA226Status { + INA226_STATUS_BUS_VOLTAGE = 0, + INA226_STATUS_SHUNT_VOLTAGE, + INA226_STATUS_CURRENT, + INA226_STATUS_POWER, +} INA226Status; + +typedef enum INA226Config { + INA226_CONFIG_CURRENT_LIM = 0, +} INA226Config; + +typedef enum INA226Alert { + INA226_ALERT_OVERCURRENT = 0, +} INA226Alert; + +static bool _get_status(void *driver, unsigned int param_id, + void *return_buf) { + switch (param_id) { + case INA226_STATUS_BUS_VOLTAGE: { + uint16_t *res = return_buf; + return (ina226_readBusVoltage(driver, res) == RETURN_OK); + } + case INA226_STATUS_SHUNT_VOLTAGE: { + uint16_t *res = return_buf; + return (ina226_readShuntVoltage(driver, res) == RETURN_OK); + } + case INA226_STATUS_CURRENT: { + uint16_t *res = return_buf; + return (ina226_readCurrent(driver, res) == RETURN_OK); + } + case INA226_STATUS_POWER: { + uint16_t *res = return_buf; + return (ina226_readPower(driver, res) == RETURN_OK); + } + default: + LOGGER_ERROR("INA226::Unknown status param %d\n", param_id); + return false; + } +} + +static bool _get_config(void *driver, unsigned int param_id, + void *return_buf) { + switch (param_id) { + case INA226_CONFIG_CURRENT_LIM: { + uint16_t *res = return_buf; + return (ina226_readCurrentLim(driver, res) == RETURN_OK); + } + default: + LOGGER_ERROR("INA226::Unknown config param %d\n", param_id); + return false; + } +} + +static bool _set_config(void *driver, unsigned int param_id, + const void *data) { + switch (param_id) { + case INA226_CONFIG_CURRENT_LIM: { + const uint16_t *limit = data; + return (ina226_setCurrentLim(driver, *limit) == RETURN_OK); + } + default: + LOGGER_ERROR("INA226::Unknown config param %d\n", param_id); + return false; + } +} + +static ePostCode _probe(void *driver, POSTData *postData) +{ + return ina226_probe(driver,postData); +} + +static void _alert_handler(INA226_Event evt, uint16_t value, void *alert_data) +{ + if (evt != INA226_EVT_COL) { + LOGGER_WARNING("IN226::Unsupported INA event 0x%x\n", evt); + return; + } + + OCMP_GenerateAlert(alert_data, INA226_ALERT_OVERCURRENT, &value); + LOGGER_DEBUG("INA226 Event: 0x%x Current: %u\n", evt, value); +} + +static ePostCode _init(void *driver, const void *config, + const void *alert_token) +{ + if (ina226_init(driver) != RETURN_OK) { + return POST_DEV_CFG_FAIL; + } + + if (!config) { + return POST_DEV_CFG_DONE; + } + const INA226_Config *ina226_config = config; + if (ina226_setCurrentLim(driver, ina226_config->current_lim) != RETURN_OK) { + return POST_DEV_CFG_FAIL; + } + + ina226_setAlertHandler(driver, _alert_handler, (void *)alert_token); + if (ina226_enableAlert(driver, INA226_EVT_COL) != RETURN_OK) { + return POST_DEV_CFG_FAIL; + } + + return POST_DEV_CFG_DONE; +} + +const Driver_fxnTable INA226_fxnTable = { + /* Message handlers */ + .cb_probe = _probe, + .cb_init = _init, + .cb_get_status = _get_status, + .cb_get_config = _get_config, + .cb_set_config = _set_config, +}; diff --git a/firmware/ec/src/Devices/ocmp_wrappers/ocmp_iridium.c b/firmware/ec/src/Devices/ocmp_wrappers/ocmp_iridium.c new file mode 100644 index 0000000000..6edccab4ae --- /dev/null +++ b/firmware/ec/src/Devices/ocmp_wrappers/ocmp_iridium.c @@ -0,0 +1,90 @@ +/** + * Copyright (c) 2017-present, Facebook, Inc. + * All rights reserved. + * + * This source code is licensed under the BSD-style license found in the + * LICENSE file in the root directory of this source tree. An additional grant + * of patent rights can be found in the PATENTS file in the same directory. + */ + +//***************************************************************************** +// HEADER FILES +//***************************************************************************** +#include "common/inc/ocmp_wrappers/ocmp_iridium.h" + +#include +#include "inc/common/global_header.h" + +static ePostCode _probe(void **driver) +{ + /* TODO: this is a problem: we can't probe until we've initialized, but we + * don't init until after probing */ + return POST_DEV_FOUND; +} + +static ePostCode _init(void *driver, const void *config, + const void *alert_token) +{ + if (sbd_init(driver) != RETURN_OK) { + return POST_DEV_CFG_FAIL; + } + return POST_DEV_CFG_DONE; +} + +static bool _get_status(void *driver, unsigned int param_id, + void *return_buf) { + bool ret = false; + switch (param_id) { + case IRIDIUM_NO_OUT_MSG: + { + ret = sbd9603_get_queueLength(return_buf); + break; + } + case IRIDIUM_LASTERR: + { + ret = sbd9603_get_lastError(return_buf); + break; + } + case IRIDIUM_IMEI: + { + ret = sbd9603_get_imei(return_buf); + break; + } + case IRIDIUM_MFG: + { + ret = sbd9603_get_mfg(return_buf); + break; + } + /* TODO: optimize this - no reason to call CSQ twice */ + case IRIDIUM_MODEL: + { + ret = sbd9603_get_model(return_buf); + break; + } + case IRIDIUM_SIG_QUALITY: + { + ret = sbd9603_get_signalqual(return_buf); + break; + } + case IRIDIUM_REGSTATUS: + { + ret = sbd9603_get_regStatus(return_buf); + break; + } + default: + LOGGER("OBC::ERROR: Unknown param %d\n", param_id); + return false; + } + return ret; +} + +const Driver_fxnTable OBC_fxnTable = { + /* Message handlers */ + .cb_probe = _probe, + .cb_init = _init, + .cb_get_status = _get_status, +}; + + + + diff --git a/firmware/ec/src/Devices/ocmp_wrappers/ocmp_led.c b/firmware/ec/src/Devices/ocmp_wrappers/ocmp_led.c new file mode 100644 index 0000000000..4a4030f21b --- /dev/null +++ b/firmware/ec/src/Devices/ocmp_wrappers/ocmp_led.c @@ -0,0 +1,72 @@ + +/** + * Copyright (c) 2017-present, Facebook, Inc. + * All rights reserved. + * + * This source code is licensed under the BSD-style license found in the + * LICENSE file in the root directory of this source tree. An additional grant + * of patent rights can be found in the PATENTS file in the same directory. + */ +#include "common/inc/ocmp_wrappers/ocmp_led.h" + +#include "inc/devices/led.h" + +/* TODO: Implement enable and disable led commands in future if nedded */ +bool led_testpattern_control(void *driver, void *param) +{ + ReturnStatus status = RETURN_OK; + ledTestParam *testPattern = (ledTestParam*)param; + switch (*testPattern) { + case HCI_LED_OFF: + { + status = hci_led_turnoff_all(driver); + break; + } + case HCI_LED_RED: + { + status = hci_led_turnon_red(driver); + break; + } + case HCI_LED_GREEN: + { + status = hci_led_turnon_green(driver); + break; + } + default: + { + LOGGER_ERROR("HCILED::Unknown param %d\n", *testPattern); + status = RETURN_NOTOK; + } + } + return (status == RETURN_OK); +} + +static ePostCode _probe(void *driver, POSTData* postData) +{ + led_configure(driver); + return led_probe(driver, postData); +} + +static ePostCode _init(void *driver, const void *config, + const void *alert_token) +{ + if (led_init(driver) != RETURN_OK) { + return POST_DEV_CFG_FAIL; + } + + if (hci_led_system_boot(driver) != RETURN_OK) { + return POST_DEV_CFG_FAIL; + } + + return POST_DEV_CFG_DONE; +} + +const Driver_fxnTable LED_fxnTable = { + /* Message handlers */ + .cb_probe = _probe, + .cb_init = _init, + .cb_get_status = NULL, + .cb_get_config = NULL, + .cb_set_config = NULL, +}; + diff --git a/firmware/ec/src/Devices/ocmp_wrappers/ocmp_ltc4015.c b/firmware/ec/src/Devices/ocmp_wrappers/ocmp_ltc4015.c new file mode 100644 index 0000000000..55f67e7758 --- /dev/null +++ b/firmware/ec/src/Devices/ocmp_wrappers/ocmp_ltc4015.c @@ -0,0 +1,321 @@ +/** + * Copyright (c) 2017-present, Facebook, Inc. + * All rights reserved. + * + * This source code is licensed under the BSD-style license found in the + * LICENSE file in the root directory of this source tree. An additional grant + * of patent rights can be found in the PATENTS file in the same directory. + */ +#include "common/inc/ocmp_wrappers/ocmp_ltc4015.h" + +#include "inc/devices/ltc4015.h" + +typedef enum LTC4015Status { + LTC4015_STATUS_BATTERY_VOLTAGE = 0, + LTC4015_STATUS_BATTERY_CURRENT, + LTC4015_STATUS_SYSTEM_VOLTAGE, + LTC4015_STATUS_INPUT_VOLATGE, + LTC4015_STATUS_INPUT_CURRENT, + LTC4015_STATUS_DIE_TEMPERATURE, + LTC4015_STATUS_ICHARGE_DAC +} LTC4015Status; + +typedef enum LTC4015Config { + LTC4015_CONFIG_BATTERY_VOLTAGE_LOW = 0, + LTC4015_CONFIG_BATTERY_VOLTAGE_HIGH, + LTC4015_CONFIG_BATTERY_CURRENT_LOW, + LTC4015_CONFIG_INPUT_VOLTAGE_LOW, + LTC4015_CONFIG_INPUT_CURRENT_HIGH, + LTC4015_CONFIG_INPUT_CURRENT_LIMIT, + LTC4015_CONFIG_ICHARGE, + LTC4015_CONFIG_VCHARGE, + LTC4015_CONFIG_DIE_TEMPERATURE_HIGH, +} LTC4015Config; + +typedef enum LTC4015Alert { + LTC4015_ALERT_BATTERY_VOLTAGE_LOW = 0, + LTC4015_ALERT_BATTERY_VOLTAGE_HIGH, + LTC4015_ALERT_BATTERY_CURRENT_LOW, + LTC4015_ALERT_INPUT_VOLTAGE_LOW, + LTC4015_ALERT_INPUT_CURRENT_HIGH, + LTC4015_ALERT_DIE_TEMPERATURE_HIGH, +} LTC4015Alert; + +static bool _choose_battery_charger(LTC4015_Dev *dev) { + if (OcGpio_write(&dev->cfg.pin_lt4015_i2c_sel, + (dev->cfg.chem == LTC4015_CHEM_LI_ION)) < OCGPIO_SUCCESS) { + return false; + } + return true; +} + +static bool _get_status(void *driver, unsigned int param_id, + void *return_buf) { + if(!_choose_battery_charger(driver)) + return false; + + switch (param_id) { + case LTC4015_STATUS_BATTERY_VOLTAGE: { + int16_t *res = return_buf; + return (LTC4015_get_battery_voltage(driver, res) == RETURN_OK); + } + case LTC4015_STATUS_BATTERY_CURRENT: { + int16_t *res = return_buf; + return (LTC4015_get_battery_current(driver, res) == RETURN_OK); + } + case LTC4015_STATUS_SYSTEM_VOLTAGE: { + int16_t *res = return_buf; + return (LTC4015_get_system_voltage(driver, res) == RETURN_OK); + } + case LTC4015_STATUS_INPUT_VOLATGE: { + int16_t *res = return_buf; + return (LTC4015_get_input_voltage(driver, res) == RETURN_OK); + } + case LTC4015_STATUS_INPUT_CURRENT: { + int16_t *res = return_buf; + return (LTC4015_get_input_current(driver, res) == RETURN_OK); + } + case LTC4015_STATUS_DIE_TEMPERATURE: { + int16_t *res = return_buf; + return (LTC4015_get_die_temperature(driver, res) == RETURN_OK); + } + case LTC4015_STATUS_ICHARGE_DAC: { + int16_t *res = return_buf; + return (LTC4015_get_icharge_dac(driver, res) == RETURN_OK); + } + default: + LOGGER_ERROR("LTC4015::Unknown status param %d\n", param_id); + return false; + } +} + +static bool _get_config(void *driver, unsigned int param_id, + void *return_buf) { + + if(!_choose_battery_charger(driver)) + return false; + + switch (param_id) { + case LTC4015_CONFIG_BATTERY_VOLTAGE_LOW: { + int16_t *res = return_buf; + return (LTC4015_get_cfg_battery_voltage_low(driver, res) + == RETURN_OK); + } + case LTC4015_CONFIG_BATTERY_VOLTAGE_HIGH: { + int16_t *res = return_buf; + return (LTC4015_get_cfg_battery_voltage_high(driver, res) + == RETURN_OK); + } + case LTC4015_CONFIG_BATTERY_CURRENT_LOW: { + int16_t *res = return_buf; + return (LTC4015_get_cfg_battery_current_low(driver, res) + == RETURN_OK); + } + case LTC4015_CONFIG_INPUT_VOLTAGE_LOW: { + int16_t *res = return_buf; + return (LTC4015_get_cfg_input_voltage_low(driver, res) + == RETURN_OK); + } + case LTC4015_CONFIG_INPUT_CURRENT_HIGH: { + int16_t *res = return_buf; + return (LTC4015_get_cfg_input_current_high(driver, res) + == RETURN_OK); + } + case LTC4015_CONFIG_INPUT_CURRENT_LIMIT: { + uint16_t *res = return_buf; + return (LTC4015_get_cfg_input_current_limit(driver, res) + == RETURN_OK); + } + case LTC4015_CONFIG_ICHARGE: { + uint16_t *res = return_buf; + return (LTC4015_get_cfg_icharge(driver, res) == RETURN_OK); + } + case LTC4015_CONFIG_VCHARGE: { + uint16_t *res = return_buf; + return (LTC4015_get_cfg_vcharge(driver, res) == RETURN_OK); + } + case LTC4015_CONFIG_DIE_TEMPERATURE_HIGH: { + int16_t *res = return_buf; + return (LTC4015_get_cfg_die_temperature_high(driver, res) + == RETURN_OK); + } + default: + LOGGER_ERROR("LTC4015::Unknown config param %d\n", param_id); + return false; + } +} + +static bool _set_config(void *driver, unsigned int param_id, + const void *data) { + if(!_choose_battery_charger(driver)) + return false; + + switch (param_id) { + case LTC4015_CONFIG_BATTERY_VOLTAGE_LOW: { + const int16_t *limit = data; + return (LTC4015_cfg_battery_voltage_low(driver, *limit) + == RETURN_OK); + } + case LTC4015_CONFIG_BATTERY_VOLTAGE_HIGH: { + const int16_t *limit = data; + return (LTC4015_cfg_battery_voltage_high(driver, *limit) + == RETURN_OK); + } + case LTC4015_CONFIG_BATTERY_CURRENT_LOW: { + const int16_t *limit = data; + return (LTC4015_cfg_battery_current_low(driver, *limit) + == RETURN_OK); + } + case LTC4015_CONFIG_INPUT_VOLTAGE_LOW: { + const int16_t *limit = data; + return (LTC4015_cfg_input_voltage_low(driver, *limit) + == RETURN_OK); + } + case LTC4015_CONFIG_INPUT_CURRENT_HIGH: { + const int16_t *limit = data; + return (LTC4015_cfg_input_current_high(driver, *limit) + == RETURN_OK); + } + case LTC4015_CONFIG_INPUT_CURRENT_LIMIT: { + const uint16_t *limit = data; + return (LTC4015_cfg_input_current_limit(driver, *limit) + == RETURN_OK); + } + case LTC4015_CONFIG_ICHARGE: { + const uint16_t *limit = data; + return (LTC4015_cfg_icharge(driver, *limit) == RETURN_OK); + } + case LTC4015_CONFIG_VCHARGE: { + const uint16_t *limit = data; + return (LTC4015_cfg_vcharge(driver, *limit) == RETURN_OK); + } + case LTC4015_CONFIG_DIE_TEMPERATURE_HIGH: { + const int16_t *limit = data; + return (LTC4015_cfg_die_temperature_high(driver, *limit) + == RETURN_OK); + } + default: + LOGGER_ERROR("LTC4015::Unknown config param %d\n", param_id); + return false; + } +} + +static ePostCode _probe(void *driver, POSTData *postData) +{ + LTC4015_configure(driver); + if(!_choose_battery_charger(driver)) + return false; + + return LTC4015_probe(driver, postData); +} + +static void _alert_handler(LTC4015_Event evt, int16_t value, void *alert_data) +{ + unsigned int alert; + switch (evt) { + case LTC4015_EVT_BVL: + alert = LTC4015_ALERT_BATTERY_VOLTAGE_LOW; + break; + case LTC4015_EVT_BVH: + alert = LTC4015_ALERT_BATTERY_VOLTAGE_HIGH; + break; + case LTC4015_EVT_BCL: + alert = LTC4015_ALERT_BATTERY_CURRENT_LOW; + break; + case LTC4015_EVT_IVL: + alert = LTC4015_ALERT_INPUT_VOLTAGE_LOW; + break; + case LTC4015_EVT_ICH: + alert = LTC4015_ALERT_INPUT_CURRENT_HIGH; + break; + case LTC4015_EVT_DTH: + alert = LTC4015_ALERT_DIE_TEMPERATURE_HIGH; + break; + default: + LOGGER_ERROR("Unknown LTC4015 evt: %d\n", evt); + return; + } + + OCMP_GenerateAlert(alert_data, alert, &value); + LOGGER_DEBUG("LTC4015 Event: %d Value: %d\n", evt, value); +} + +static ePostCode _init(void *driver, const void *config, + const void *alert_token) { + if(!_choose_battery_charger(driver)) + return false; + + if (LTC4015_init(driver) != RETURN_OK) { + return POST_DEV_CFG_FAIL; + } + + if (!config) { + return POST_DEV_CFG_DONE; + } + + const LTC4015_Config *ltc4015_config = config; + + if (LTC4015_cfg_battery_voltage_low(driver, + ltc4015_config->batteryVoltageLow) + != RETURN_OK) { + return POST_DEV_CFG_FAIL; + } + if (LTC4015_cfg_battery_voltage_high(driver, + ltc4015_config->batteryVoltageHigh) + != RETURN_OK) { + return POST_DEV_CFG_FAIL; + } + if (LTC4015_cfg_battery_current_low(driver, + ltc4015_config->batteryCurrentLow) + != RETURN_OK) { + return POST_DEV_CFG_FAIL; + } + if (LTC4015_cfg_input_voltage_low(driver, ltc4015_config->inputVoltageLow) + != RETURN_OK) { + return POST_DEV_CFG_FAIL; + } + if (LTC4015_cfg_input_current_high(driver, ltc4015_config->inputCurrentHigh) + != RETURN_OK) { + return POST_DEV_CFG_FAIL; + } + if (LTC4015_cfg_input_current_limit(driver, + ltc4015_config->inputCurrentLimit) + != RETURN_OK) { + return POST_DEV_CFG_FAIL; + } + if (ltc4015_config->icharge) { + if (LTC4015_cfg_icharge(driver, ltc4015_config->icharge) + != RETURN_OK) { + return POST_DEV_CFG_FAIL; + } + } + if (ltc4015_config->vcharge) { + if (LTC4015_cfg_vcharge(driver, ltc4015_config->vcharge) + != RETURN_OK) { + return POST_DEV_CFG_FAIL; + } + } + + LTC4015_setAlertHandler(driver, _alert_handler, (void *)alert_token); + if (LTC4015_enableLimitAlerts(driver, + LTC4015_EVT_BVL | LTC4015_EVT_BVH + | LTC4015_EVT_IVL | LTC4015_EVT_ICH + | LTC4015_EVT_BCL) != RETURN_OK) { + return POST_DEV_CFG_FAIL; + } + + if (LTC4015_enableChargerStateAlerts(driver, LTC4015_EVT_BMFA)) { + return POST_DEV_CFG_FAIL; + } + + return POST_DEV_CFG_DONE; +} + +const Driver_fxnTable LTC4015_fxnTable = { + /* Message handlers */ + .cb_probe = _probe, + .cb_init = _init, + .cb_get_status = _get_status, + .cb_get_config = _get_config, + .cb_set_config = _set_config, +}; diff --git a/firmware/ec/src/Devices/ocmp_wrappers/ocmp_ltc4274.c b/firmware/ec/src/Devices/ocmp_wrappers/ocmp_ltc4274.c new file mode 100644 index 0000000000..b0eef146aa --- /dev/null +++ b/firmware/ec/src/Devices/ocmp_wrappers/ocmp_ltc4274.c @@ -0,0 +1,279 @@ +/** + * Copyright (c) 2017-present, Facebook, Inc. + * All rights reserved. + * + * This source code is licensed under the BSD-style license found in the + * LICENSE file in the root directory of this source tree. An additional grant + * of patent rights can be found in the PATENTS file in the same directory. + */ +#include "common/inc/ocmp_wrappers/ocmp_ltc4274.h" + +#include "helpers/array.h" +#include "helpers/math.h" +#include "inc/devices/ltc4274.h" + +typedef enum LTC7274Status { + LTC7274_STATUS_DETECT = 0, + LTC7274_STATUS_CLASS , + LTC7274_STATUS_POWERGOOD, +} LTC7274Status; + +typedef enum LTC7274Config { + LTC4274_CONFIG_OPERATING_MODE = 0, + LTC4274_CONFIG_DETECT_ENABLE, + LTC4274_CONFIG_INTERRUPT_MASK, + LTC4274_CONFIG_INTERRUPT_ENABLE, + LTC4274_CONFIG_HP_ENABLE +} LTC7274Config; + +typedef enum LTC7274Alert { + LTC4274_ALERT_NO_ACTIVE = 0, + LTC4274_ALERT_POWER_ENABLE, + LTC4274_ALERT_POWERGOOD, + LTC4274_ALERT_DISCONNECT, + LTC4274_ALERT_DETECTION , + LTC4274_ALERT_CLASS, + LTC4274_ALERT_TCUT, + LTC4274_ALERT_TSTART, + LTC4274_ALERT_SUPPLY +} LTC7274Alert; + +bool LTC4274_reset(void *driver, void *params) +{ + ReturnStatus status = RETURN_OK; + status = ltc4274_reset(); + return status; +} + +static bool _get_status(void *driver, unsigned int param_id, + void *return_buf) { + bool ret = true; + uint8_t *res = return_buf; + switch (param_id) { + case LTC7274_STATUS_DETECT: + { + if (ltc4274_get_detection_status(driver, res) != RETURN_OK) { + ret = false; + LOGGER("LTC4274:ERROR:: Reading PSE detection and classification failed.\n"); + } + break; + } + case LTC7274_STATUS_CLASS: + { + if (ltc4274_get_class_status(driver, res) != RETURN_OK) { + ret = false; + LOGGER("LTC4274:ERROR:: Reading PSE power status failed.\n"); + } + break; + } + case LTC7274_STATUS_POWERGOOD: + { + if (ltc4274_get_powergood_status(driver, res) != RETURN_OK) { + ret = false; + LOGGER("LTC4274:ERROR:: Reading PSE power status failed.\n"); + return ret; + } + break; + } + default: + { + LOGGER("LTC4274:ERROR::Unkown parameter recived for PSE status.\n"); + ret = false; + } + } + return ret; +} + +static bool _set_config(void *driver, unsigned int param_id, + const void *data) { + bool ret = true; + uint8_t *res = (uint8_t*)data; + switch (param_id) { + case LTC4274_CONFIG_OPERATING_MODE: + { + if ( ltc4274_set_cfg_operation_mode(driver, *res) != RETURN_OK) { + ret = false; + LOGGER("LTC4274:ERROR:: PSE operational mode setting mode failed.\n"); + } + break; + } + case LTC4274_CONFIG_DETECT_ENABLE: + { + if (ltc4274_set_cfg_detect_enable(driver, *res) != RETURN_OK) { + ret = false; + LOGGER("LTC4274:ERROR:: PSE detection and classification enable failed.\n"); + } + break; + } + case LTC4274_CONFIG_INTERRUPT_MASK: + { + if (ltc4274_set_interrupt_mask(driver, *res) != RETURN_OK) { + ret = false; + LOGGER("LTC4274:ERROR::PSE interrupts mask enable failed.\n"); + } + break; + } + case LTC4274_CONFIG_INTERRUPT_ENABLE: + { + if (ltc4274_cfg_interrupt_enable(driver, *res) != RETURN_OK) { + ret = false; + LOGGER("LTC4274:ERROR:: PSE interrupt enable failed.\n"); + } + break; + } + case LTC4274_CONFIG_HP_ENABLE: + { + if (ltc4274_set_cfg_pshp_feature(driver, *res) != RETURN_OK) { + ret = false; + LOGGER("LTC4274:ERROR:: PSE configuration for LTEPOE++ failed.\n"); + } + break; + } + default: + { + LOGGER("LTC4274:ERROR:: PSE configurion unkown parmeter passed.\n"); + ret = false; + } + } + return ret; +} + +static bool _get_config(void *driver, unsigned int param_id, + void *return_buf) { + bool ret = true; + uint8_t *res = return_buf; + switch (param_id) { + case LTC4274_CONFIG_OPERATING_MODE: + { + if (ltc4274_get_operation_mode(driver, res) != RETURN_OK) { + ret = false; + LOGGER("LTC4274:ERROR:: PSE operational mode setting mode failed.\n"); + } + break; + } + case LTC4274_CONFIG_DETECT_ENABLE: + { + if (ltc4274_get_detect_enable(driver, res)!= RETURN_OK) { + ret = false; + LOGGER("LTC4274:ERROR:: PSE detection and classification enable failed.\n"); + } + break; + } + case LTC4274_CONFIG_INTERRUPT_MASK: + { + if (ltc4274_get_interrupt_mask(driver, res) != RETURN_OK) { + ret = false; + LOGGER("LTC4274:ERROR::PSE interrupts mask enable failed.\n"); + } + break; + } + case LTC4274_CONFIG_INTERRUPT_ENABLE: + { + if (ltc4274_get_interrupt_enable(driver, res) != RETURN_OK) { + ret = false; + LOGGER("LTC4274:ERROR:: PSE interrupt enable failed.\n"); + } + break; + } + case LTC4274_CONFIG_HP_ENABLE: + { + if (ltc4274_get_pshp_feature(driver, res) != RETURN_OK) { + ret = false; + LOGGER("LTC4274:ERROR:: PSE configuration for LTEPOE++ failed.\n"); + } + break; + } + default: + { + LOGGER("LTC4274:ERROR:: PSE configurion unkown parmeter passed.\n"); + ret = false; + } + } + return ret; +} +static ePostCode _probe(void *driver, POSTData *postData) +{ + ltc4274_config(driver); + return ltc4274_probe(driver, postData); + +} + +static void _alert_handler(LTC4274_Event evt, + void *context) +{ + unsigned int alert; + switch(evt) { + case LTC4274_EVT_SUPPLY: + alert = LTC4274_ALERT_SUPPLY; + break; + case LTC4274_EVT_TSTART: + alert = LTC4274_ALERT_TSTART; + break; + case LTC4274_EVT_TCUT: + alert = LTC4274_ALERT_TCUT; + break; + case LTC4274_EVT_CLASS: + alert = LTC4274_ALERT_CLASS; + break; + case LTC4274_EVT_DETECTION: + alert = LTC4274_ALERT_DETECTION; + break; + case LTC4274_EVT_DISCONNECT: + alert = LTC4274_ALERT_DISCONNECT; + break; + case LTC4274_EVT_POWERGOOD: + alert = LTC4274_ALERT_POWERGOOD; + break; + case LTC4274_EVT_POWER_ENABLE: + alert = LTC4274_ALERT_POWER_ENABLE; + break; + default: + { + alert = LTC4274_ALERT_NO_ACTIVE; + return; + } + } + uint8_t alert_data = 0x00; + OCMP_GenerateAlert(context, alert, &alert_data); + LOGGER_DEBUG("LTC7274 Event: %d \n", evt); +} + +static ePostCode _init(void *driver, const void *config, + const void *alert_token) +{ + ltc4274_init(driver); + + if (!config) { + return POST_DEV_CFG_DONE; + } + const LTC4274_Config *LTC7274_config = config; + if ( ltc4274_set_cfg_operation_mode(driver,LTC7274_config->operatingMode) != RETURN_OK) { + return POST_DEV_CFG_FAIL; + } + if ( ltc4274_set_cfg_detect_enable(driver,LTC7274_config->detectEnable) != RETURN_OK) { + return POST_DEV_CFG_FAIL; + } + if ( ltc4274_set_interrupt_mask(driver,LTC7274_config->interruptMask) != RETURN_OK) { + return POST_DEV_CFG_FAIL; + } + if ( ltc4274_set_cfg_pshp_feature(driver,LTC7274_config->pseHpEnable) != RETURN_OK) { + return POST_DEV_CFG_FAIL; + } + ltc4274_set_alert_handler(driver, _alert_handler, (void *)alert_token); + //TODO: SET enable or disable. + if (ltc4274_cfg_interrupt_enable(driver, LTC7274_config->interruptEnable) != RETURN_OK) { + return POST_DEV_CFG_FAIL; + } + ltc4274_update_stateInfo(driver); + + return POST_DEV_CFG_DONE; +} + +const Driver_fxnTable LTC4274_fxnTable = { + /* Message handlers */ + .cb_probe = _probe, + .cb_init = _init, + .cb_get_status = _get_status, + .cb_get_config = _get_config, + .cb_set_config = _set_config, +}; diff --git a/firmware/ec/src/Devices/ocmp_wrappers/ocmp_ltc4275.c b/firmware/ec/src/Devices/ocmp_wrappers/ocmp_ltc4275.c new file mode 100644 index 0000000000..8f86fc9f8a --- /dev/null +++ b/firmware/ec/src/Devices/ocmp_wrappers/ocmp_ltc4275.c @@ -0,0 +1,94 @@ +/** + * Copyright (c) 2017-present, Facebook, Inc. + * All rights reserved. + * + * This source code is licensed under the BSD-style license found in the + * LICENSE file in the root directory of this source tree. An additional grant + * of patent rights can be found in the PATENTS file in the same directory. + */ +#include "common/inc/ocmp_wrappers/ocmp_ltc4275.h" + +#include "helpers/array.h" +#include "helpers/math.h" +#include "inc/devices/ltc4275.h" + +static bool _get_status(void *driver, unsigned int param_id, + void *return_buf) +{ + bool ret = false; + switch (param_id) { + case LTC4275_STATUS_CLASS: + { + ePDClassType *res = (ePDClassType*)return_buf; + if (ltc4275_get_class(driver, res) == RETURN_OK) { + ret = true; + } + } + break; + case LTC4275_STATUS_POWERGOOD: + { + ePDPowerState *res =(ePDPowerState*) return_buf; + if (ltc4275_get_power_good(driver, res) == RETURN_OK) { + ret = true; + } + break; + } + default: + { + LOGGER_ERROR("LTC4275::Unknown status param %d\n", param_id); + ret = false; + } + } + return ret; +} + +/***************************************************************************** + *****************************************************************************/ +static ePostCode _probe(void *driver, POSTData *postData) +{ + ltc4275_config(driver); + return ltc4275_probe(driver,postData); +} + +/***************************************************************************** + *****************************************************************************/ +static void _alert_handler(LTC4275_Event evt, void *context) +{ + unsigned int alert; + switch (evt) { + case LTC4275_CONNECT_EVT: + alert = LTC4275_CONNECT_ALERT; + break; + case LTC4275_DISCONNECT_EVT: + alert = LTC4275_DISCONNECT_ALERT; + break; + case LTC4275_INCOMPATIBLE_EVT: + alert = LTC4275_INCOMPATIBLE_ALERT; + break; + default: + LOGGER_ERROR("Unknown LTC4275evt: %d\n", evt); + return; + } + OCMP_GenerateAlert(context, alert, &evt); + LOGGER_DEBUG("LTC4275A alert: %d generated.\n", alert); +} + +/***************************************************************************** + *****************************************************************************/ +static ePostCode _init(void *driver, const void *config, + const void *alert_token) +{ + if (ltc4275_init(driver) != RETURN_OK) { + return POST_DEV_CFG_FAIL; + } + + ltc4275_set_alert_handler(driver, _alert_handler, (void *)alert_token); + return POST_DEV_CFG_DONE; +} + +const Driver_fxnTable LTC4275_fxnTable = { + /* Message handlers */ + .cb_probe = _probe, + .cb_init = _init, + .cb_get_status = _get_status, +}; diff --git a/firmware/ec/src/Devices/ocmp_wrappers/ocmp_mac.c b/firmware/ec/src/Devices/ocmp_wrappers/ocmp_mac.c new file mode 100644 index 0000000000..89e5514b47 --- /dev/null +++ b/firmware/ec/src/Devices/ocmp_wrappers/ocmp_mac.c @@ -0,0 +1,232 @@ +/** +* Copyright (c) 2017-present, Facebook, Inc. +* All rights reserved. +* +* This source code is licensed under the BSD-style license found in the +* LICENSE file in the root directory of this source tree. An additional grant +* of patent rights can be found in the PATENTS file in the same directory. +*/ +#include "common/inc/ocmp_wrappers/ocmp_mac.h" + +#include "inc/common/global_header.h" + +#include +#include + +typedef enum { + OC_SYS_CONF_MAC_ADDRESS = 0 +} eOCConfigParamId; + +/***************************************************************************** + ** FUNCTION NAME : _get_mac_address + ** + ** DESCRIPTION : Get EC MAC address. + ** + ** ARGUMENTS : Pointer MAC address. + ** + ** RETURN TYPE : true on Success and false on Failure + ** + *****************************************************************************/ +static ReturnStatus _get_mac_address(uint8_t *macAddress) +{ + uint32_t ulUser0 = 0, ulUser1 = 0; + + /* Get the MAC address */ + if((FlashUserGet(&ulUser0, &ulUser1)) != 0) { + return RETURN_NOTOK; + } + uint8_t i = 0; + uint8_t temp[6] = {'\0'}; + + if ((ulUser0 != 0xffffffff) && (ulUser1 != 0xffffffff)) { + /* + * Convert the 24/24 split MAC address from NV ram into a 32/16 split + * MAC address needed to program the hardware registers, then program + * the MAC address into the Ethernet Controller registers. + */ + temp[0] = ((ulUser0 >> 0) & 0xff); + temp[1] = ((ulUser0 >> 8) & 0xff); + temp[2] = ((ulUser0 >> 16) & 0xff); + temp[3] = ((ulUser1 >> 0) & 0xff); + temp[4] = ((ulUser1 >> 8) & 0xff); + temp[5] = ((ulUser1 >> 16) & 0xff); + + for( i = 0; i < 6; i++ ) + { + sprintf((char *)&macAddress[i*2], "%X", ((temp[i]&0xf0) >> 4)); + sprintf((char *)&macAddress[(i*2)+1], "%X", temp[i]&0xf); + } + } else { + strncpy((char *)macAddress, "FFFFFFFFFFFF", 12); + } + + return RETURN_OK; +} + +static uint32_t str_to_val(const char *str) +{ + uint32_t value = 0; + uint8_t temp; + char *ptr; + value = strtol(str, &ptr, 16); + temp = (value & 0XFF0000) >> 16; + value = (value & 0X00FF00) | ((value & 0X0000FF) << 16); + value = value | temp; + return value; +} + +/***************************************************************************** + ** FUNCTION NAME : _set_mac_address + ** + ** DESCRIPTION : Set EC MAC address. + ** + ** ARGUMENTS : Pointer to MAC address + ** + ** RETURN TYPE : true on Success and false on Failure + ** + *****************************************************************************/ +ReturnStatus _set_mac_address(const uint8_t *macAddress) +{ + uint32_t ulUser0, ulUser1; + if(macAddress != NULL) { + char temp[6]; + strncpy(temp, (const char *)macAddress, 6); + ulUser0 = str_to_val(temp); + strncpy(temp, (const char *)(macAddress + 6), 6); + ulUser1 = str_to_val(temp); + /* Set the MAC address */ + if((FlashUserSet(ulUser0, ulUser1)) != 0) { + return RETURN_NOTOK; + } else { + if(FlashUserSave() != 0) { + return RETURN_NOTOK; + } + } + /*SysCtlDelay(2000000); + SysCtlReset();*/ + } + + return RETURN_OK; +} + +/***************************************************************************** + ** FUNCTION NAME : mac_get_config_parameters_data + ** + ** DESCRIPTION : Get OC Config Message. + ** + ** ARGUMENTS : pointer to Driver config, Parameter info + ** and pointer to MAC Address. + ** + ** RETURN TYPE : true on Success and false on Failure + ** + *****************************************************************************/ +static bool _mac_get_config_parameters_data(void **driver, + unsigned int param, + void *pOCConfigData) +{ + const eOCConfigParamId paramIndex = (eOCConfigParamId)param; + ReturnStatus status = RETURN_OK; + switch (paramIndex) { + case OC_SYS_CONF_MAC_ADDRESS: + { + memset(pOCConfigData, '\0', OC_MAC_ADDRESS_SIZE + 1); + status = _get_mac_address(pOCConfigData); + LOGGER_DEBUG("SYS:INFO:: OC Connect1 MAC Address: %s.\n", + pOCConfigData); + break; + } + default: + { + status = RETURN_NOTOK; + } + } + return (status == RETURN_OK); +} + +/***************************************************************************** + ** FUNCTION NAME : mac_set_config_parameters_data + ** + ** DESCRIPTION : Set OC Config Message. + ** + ** ARGUMENTS : pointer to Driver config, Parameter info + ** and pointer to MAC Address. + ** + ** RETURN TYPE : true on Success and false on Failure + ** + *****************************************************************************/ +static bool _mac_set_config_parameters_data(void **driver, + unsigned int param, + const void *pOCConfigData) +{ + const eOCConfigParamId paramIndex = (eOCConfigParamId)param; + ReturnStatus status = RETURN_OK; + switch (paramIndex) { + case OC_SYS_CONF_MAC_ADDRESS: + { + LOGGER_DEBUG("SYS:INFO:: Set OC Connect1 MAC Address to: %s.\n", + pOCConfigData); + _set_mac_address(pOCConfigData); + break; + } + default: + { + status = RETURN_NOTOK; + } + } + return (status == RETURN_OK); +} + +static ePostCode _probe_mac(void *driver, const void *config, + const void *alert_token) +{ + uint8_t macAddress[14]; + uint32_t ulUser0 = 0, ulUser1 = 0; + + /* Get the MAC address */ + if((FlashUserGet(&ulUser0, &ulUser1)) != 0) { + return POST_DEV_MISSING; + } + uint8_t i = 0; + uint8_t temp[6] = {'\0'}; + + if ((ulUser0 != 0xffffffff) && (ulUser1 != 0xffffffff)) { + /* + * Convert the 24/24 split MAC address from NV ram into a 32/16 split + * MAC address needed to program the hardware registers, then program + * the MAC address into the Ethernet Controller registers. + */ + temp[0] = ((ulUser0 >> 0) & 0xff); + temp[1] = ((ulUser0 >> 8) & 0xff); + temp[2] = ((ulUser0 >> 16) & 0xff); + temp[3] = ((ulUser1 >> 0) & 0xff); + temp[4] = ((ulUser1 >> 8) & 0xff); + temp[5] = ((ulUser1 >> 16) & 0xff); + + for( i = 0; i < 6; i++ ) + { + sprintf((char *)&macAddress[i*2], "%X", ((temp[i]&0xf0) >> 4)); + sprintf((char *)&macAddress[(i*2)+1], "%X", temp[i]&0xf); + } + } else { + strncpy((char *)macAddress, "FFFFFFFFFFFF", 12); + return POST_DEV_MISSING; + } + return POST_DEV_FOUND; +} + +/* Dummy Initialize for MAC */ +static ePostCode _init_mac(void *driver, const void *config, + const void *alert_token) +{ + return POST_DEV_NO_CFG_REQ; +} + + +const Driver_fxnTable MAC_fxnTable= { + .cb_probe = _probe_mac, + .cb_init = _init_mac, + .cb_get_config = _mac_get_config_parameters_data, + .cb_set_config = _mac_set_config_parameters_data, +}; + + diff --git a/firmware/ec/src/Devices/ocmp_wrappers/ocmp_mp2951.c b/firmware/ec/src/Devices/ocmp_wrappers/ocmp_mp2951.c new file mode 100644 index 0000000000..468af51cff --- /dev/null +++ b/firmware/ec/src/Devices/ocmp_wrappers/ocmp_mp2951.c @@ -0,0 +1,89 @@ +/** + * Copyright (c) 2017-present, Facebook, Inc. + * All rights reserved. + * + * This source code is licensed under the BSD-style license found in the + * LICENSE file in the root directory of this source tree. An additional grant + * of patent rights can be found in the PATENTS file in the same directory. + */ + +#include "common/inc/global/Framework.h" +#include "inc/devices/mp2951.h" + +typedef enum MP2951Status { + MP2951_STATUS_VENDOR_ID = 0, + MP2951_STATUS_PRODUCT_ID = 1, +} MP2951Status; + +typedef enum MP2951Config { + MP2951_INPUT_VOLT_ON_LIM = 0, + MP2951_INPUT_VOLT_OFF_LIM = 1, +} MP2951Config; + +static bool _get_status(void *driver, unsigned int param_id, + void *return_buf) { + switch (param_id) { + case MP2951_STATUS_VENDOR_ID:{ + uint8_t *res = return_buf; + return (mp2951_getVendId(driver, res) == RETURN_OK); + } + case MP2951_STATUS_PRODUCT_ID:{ + uint8_t *res = return_buf; + return (mp2951_getDevId(driver, res) == RETURN_OK); + } + default: + LOGGER_ERROR("MP2951::Unknown status param %d\n", param_id); + return false; + } +} + +static bool _get_config(void *driver, unsigned int param_id, + void *return_buf) { + switch (param_id) { + case MP2951_INPUT_VOLT_ON_LIM: { + uint16_t *res = return_buf; + return (MP2951_readInputVolOnLim(driver, res) == RETURN_OK); + } + case MP2951_INPUT_VOLT_OFF_LIM: { + uint16_t *res = return_buf; + return (MP2951_readInputVolOffLim(driver, res) == RETURN_OK); + } + default: + LOGGER_ERROR("MP2951::Unknown config param %d\n", param_id); + return false; + } +} + +static bool _set_config(void *driver, unsigned int param_id, + const void *data) { + switch (param_id) { + case MP2951_INPUT_VOLT_ON_LIM: { + const uint16_t *res = data; + return (MP2951_setInputVolOnLim(driver, *res) == RETURN_OK); + } + case MP2951_INPUT_VOLT_OFF_LIM: { + const uint16_t *res = data; + return (MP2951_setInputVolOffLim(driver, *res) == RETURN_OK); + } + default: + LOGGER_ERROR("MP2951::Unknown config param %d\n", param_id); + return false; + } +} +static ePostCode _probe(void *driver, POSTData *postData) +{ + return mp2951_probe(driver,postData); +} +static ePostCode _init(void *driver, const void *config, + const void *alert_token) +{ + return POST_DEV_CFG_DONE; +} +const Driver_fxnTable MP2951_fxnTable = { + /* Message handlers */ + .cb_probe = _probe, + .cb_init = _init, + .cb_get_status = _get_status, + .cb_get_config = _get_config, + .cb_set_config = _set_config, +}; diff --git a/firmware/ec/src/Devices/ocmp_wrappers/ocmp_powerSource.c b/firmware/ec/src/Devices/ocmp_wrappers/ocmp_powerSource.c new file mode 100644 index 0000000000..07d841b92b --- /dev/null +++ b/firmware/ec/src/Devices/ocmp_wrappers/ocmp_powerSource.c @@ -0,0 +1,46 @@ +/** + * Copyright (c) 2017-present, Facebook, Inc. + * All rights reserved. + * + * This source code is licensed under the BSD-style license found in the + * LICENSE file in the root directory of this source tree. An additional grant + * of patent rights can be found in the PATENTS file in the same directory. + */ +#include "common/inc/ocmp_wrappers/ocmp_powersource.h" + +#include "common/inc/global/Framework.h" +#include "inc/devices/powerSource.h" +#include "helpers/array.h" + +static bool _get_status(void *driver, unsigned int param_id, + void *return_buf) +{ + bool ret = false; + /* TODO: As of now using pwr_get_sourc_info as it is for Power source Update. + * Once we change the handing of the powersource status #298 this will also changed. */ + pwr_get_source_info(driver); + if ( pwr_process_get_status_parameters_data(param_id,return_buf) == RETURN_OK) { + ret = true; + } + return ret; +} + +static ePostCode _probe(void *driver) +{ + pwr_source_config(driver); + return POST_DEV_NOSTATUS; +} + +static ePostCode _init(void *driver, const void *config, + const void *alert_token) +{ + pwr_source_init(); + return POST_DEV_NO_CFG_REQ; +} + +const Driver_fxnTable PWRSRC_fxnTable = { + /* Message handlers */ + .cb_probe = _probe, + .cb_init = _init, + .cb_get_status = _get_status, +}; diff --git a/firmware/ec/src/Devices/ocmp_wrappers/ocmp_rfpowermonitor.c b/firmware/ec/src/Devices/ocmp_wrappers/ocmp_rfpowermonitor.c new file mode 100644 index 0000000000..f38ca300ae --- /dev/null +++ b/firmware/ec/src/Devices/ocmp_wrappers/ocmp_rfpowermonitor.c @@ -0,0 +1,42 @@ +/** + * Copyright (c) 2017-present, Facebook, Inc. + * All rights reserved. + * + * This source code is licensed under the BSD-style license found in the + * LICENSE file in the root directory of this source tree. An additional grant + * of patent rights can be found in the PATENTS file in the same directory. + */ +#include "common/inc/ocmp_wrappers/ocmp_rfpowermonitor.h" + +#include "inc/subsystem/rffe/rffe_powermonitor.h" + +/* OCMP message handler */ +static bool _ocmp_get_status(void *driver, unsigned int param_id, + void *return_buf) { + switch (param_id) { + case FE_POWER_STATUS_FORWARD: { + if (rffe_powermonitor_read_power(driver, + RFFE_STAT_FW_POWER, + return_buf) == RETURN_OK) { + return true; + } + break; + } + case FE_POWER_STATUS_REVERSE: { + if (rffe_powermonitor_read_power(driver, + RFFE_STAT_REV_POWER, + return_buf) == RETURN_OK) { + return true; + } + break; + } + default: + LOGGER_ERROR("RFPOWERMONITOR::Unknown status param %d\n", param_id); + return false; + } + return false; +} + +const Driver_fxnTable RFPowerMonitor_fxnTable = { + .cb_get_status = _ocmp_get_status, +}; diff --git a/firmware/ec/src/Devices/ocmp_wrappers/ocmp_rfwatchdog.c b/firmware/ec/src/Devices/ocmp_wrappers/ocmp_rfwatchdog.c new file mode 100644 index 0000000000..11fca7e1d3 --- /dev/null +++ b/firmware/ec/src/Devices/ocmp_wrappers/ocmp_rfwatchdog.c @@ -0,0 +1,37 @@ +/** + * Copyright (c) 2017-present, Facebook, Inc. + * All rights reserved. + * + * This source code is licensed under the BSD-style license found in the + * LICENSE file in the root directory of this source tree. An additional grant + * of patent rights can be found in the PATENTS file in the same directory. + */ +#include "common/inc/ocmp_wrappers/ocmp_rfwatchdog.h" + +#include "inc/subsystem/rffe/rffe_ctrl.h" + +static ePostCode _rffe_watchdog_init(void *driver, const void *config, + const void *alert_token) +{ + RfWatchdog_Cfg *cfg = (RfWatchdog_Cfg *)driver; + if (OcGpio_configure(cfg->pin_alert_lb, OCGPIO_CFG_INPUT)) { + return POST_DEV_CFG_FAIL; + } + if (OcGpio_configure(cfg->pin_alert_hb, OCGPIO_CFG_INPUT)) { + return POST_DEV_CFG_FAIL; + } + if (OcGpio_configure(cfg->pin_interrupt, OCGPIO_CFG_INPUT | + OCGPIO_CFG_INT_FALLING)) { + return POST_DEV_CFG_FAIL; + } + + ThreadedInt_Init(cfg->pin_interrupt, _rffe_watchdog_handler, cfg); + return POST_DEV_CFG_DONE; +} + +const Driver_fxnTable RFFEWatchdogP_fxnTable = { + .cb_init = _rffe_watchdog_init, +}; + + + diff --git a/firmware/ec/src/Devices/ocmp_wrappers/ocmp_se98a.c b/firmware/ec/src/Devices/ocmp_wrappers/ocmp_se98a.c new file mode 100644 index 0000000000..3ecc7bb65e --- /dev/null +++ b/firmware/ec/src/Devices/ocmp_wrappers/ocmp_se98a.c @@ -0,0 +1,147 @@ +/** + * Copyright (c) 2017-present, Facebook, Inc. + * All rights reserved. + * + * This source code is licensed under the BSD-style license found in the + * LICENSE file in the root directory of this source tree. An additional grant + * of patent rights can be found in the PATENTS file in the same directory. + */ +#include "common/inc/ocmp_wrappers/ocmp_se98a.h" + +#include "helpers/array.h" +#include "helpers/math.h" +#include "inc/devices/se98a.h" + +typedef enum Se98aStatus { + SE98A_STATUS_TEMPERATURE = 0, +} Se98aStatus; + +typedef enum Se98aConfig { + SE98A_CONFIG_LIM_LOW = 0, + SE98A_CONFIG_LIM_HIGH, + SE98A_CONFIG_LIM_CRIT, +} Se98aConfig; + +typedef enum Se98aAlert { + SE98A_ALERT_LOW = 0, + SE98A_ALERT_HIGH, + SE98A_ALERT_CRITICAL +} Se98aAlert; + +static bool _get_status(void *driver, unsigned int param_id, + void *return_buf) { + switch (param_id) { + case SE98A_STATUS_TEMPERATURE: { + int8_t *res = return_buf; + if (se98a_read(driver, res) == RETURN_OK) { + return true; + } + break; + } + default: + LOGGER_ERROR("SE98A::Unknown status param %d\n", param_id); + return false; + } + return false; +} + +static bool _get_config(void *driver, unsigned int param_id, + void *return_buf) { + switch (param_id) { + case SE98A_CONFIG_LIM_LOW: + case SE98A_CONFIG_LIM_HIGH: + case SE98A_CONFIG_LIM_CRIT: { + int8_t *res = return_buf; + if (se98a_get_limit(driver, param_id + 1, res) == RETURN_OK) { + return true; + } + break; + } + default: + LOGGER_ERROR("SE98A::Unknown config param %d\n", param_id); + return false; + } + return false; +} + +static bool _set_config(void *driver, unsigned int param_id, + const void *data) { + switch (param_id) { + case SE98A_CONFIG_LIM_LOW: + case SE98A_CONFIG_LIM_HIGH: + case SE98A_CONFIG_LIM_CRIT: { + const int8_t *limit = data; + if (se98a_set_limit(driver, param_id + 1, *limit) == RETURN_OK) { + return true; + } + break; + } + default: + LOGGER_ERROR("SE98A::Unknown config param %d\n", param_id); + return false; + } + return false; +} + +static ePostCode _probe(void *driver, POSTData *postData) +{ + return se98a_probe(driver, postData); +} + +static void _alert_handler(SE98A_Event evt, int8_t temperature, + void *context) +{ + unsigned int alert; + switch (evt) { + case SE98A_EVT_ACT: + alert = SE98A_ALERT_CRITICAL; + break; + case SE98A_EVT_AAW: + alert = SE98A_ALERT_HIGH; + break; + case SE98A_EVT_BAW: + alert = SE98A_ALERT_LOW; + break; + default: + LOGGER_ERROR("Unknown SE98A evt: %d\n", evt); + return; + } + + uint8_t alert_data = (uint8_t)MAX((int8_t)0, temperature); + OCMP_GenerateAlert(context, alert, &alert_data); + LOGGER_DEBUG("SE98A Event: %d Temperature: %d\n", evt, temperature); +} + +static ePostCode _init(void *driver, const void *config, + const void *alert_token) +{ + if (se98a_init(driver) != RETURN_OK) { + return POST_DEV_CFG_FAIL; + } + if (!config) { + return POST_DEV_CFG_DONE; + } + const SE98A_Config *se98a_config = config; + for (int i = 0; i < ARRAY_SIZE(se98a_config->limits); ++i) { + if (se98a_set_limit(driver, i + 1, se98a_config->limits[i]) != + RETURN_OK) { + return POST_DEV_CFG_FAIL; + } + } + + se98a_set_alert_handler(driver, _alert_handler, (void *)alert_token); + if (se98a_enable_alerts(driver) != RETURN_OK) { + return POST_DEV_CFG_FAIL; + } + + return POST_DEV_CFG_DONE; +} + +const Driver_fxnTable SE98_fxnTable = { + /* Message handlers */ + .cb_probe = _probe, + .cb_init = _init, + .cb_get_status = _get_status, + .cb_get_config = _get_config, + .cb_set_config = _set_config, +}; diff --git a/firmware/ec/src/Devices/ocmp_wrappers/ocmp_si1141.c b/firmware/ec/src/Devices/ocmp_wrappers/ocmp_si1141.c new file mode 100644 index 0000000000..09d3a48158 --- /dev/null +++ b/firmware/ec/src/Devices/ocmp_wrappers/ocmp_si1141.c @@ -0,0 +1,65 @@ +/** + * Copyright (c) 2017-present, Facebook, Inc. + * All rights reserved. + * + * This source code is licensed under the BSD-style license found in the + * LICENSE file in the root directory of this source tree. An additional grant + * of patent rights can be found in the PATENTS file in the same directory. + */ + +#include "common/inc/global/Framework.h" +#include "inc/devices/si1141.h" + +typedef enum SI1141Status { + SI1141_STATUS_PART_ID = 0, + SI1141_STATUS_REV_ID, + SI1141_STATUS_SEQ_ID, +} SI1141Status; + +static bool _get_status(void *driver, unsigned int param_id, + void *return_buf) { + switch (param_id) { + case SI1141_STATUS_PART_ID: { + uint16_t *res = return_buf; + return (si1141_getPartId(driver, res) == RETURN_OK); + } + case SI1141_STATUS_REV_ID: { + uint16_t *res = return_buf; + return (si1141_getRevId(driver, res) == RETURN_OK); + } + case SI1141_STATUS_SEQ_ID: { + uint16_t *res = return_buf; + return (si1141_getSeqId(driver, res) == RETURN_OK); + } + default: + LOGGER_ERROR("SI1141::Unknown status param %d\n", param_id); + return false; + } +} + +static ePostCode _probe(void *driver, POSTData *postData) +{ + return si1141_probe(driver, postData); +} + +static ePostCode _init(void *driver, const void *config, + const void *alert_token) +{ + /* if (si1141_init(driver) != RETURN_OK) { + return POST_DEV_CFG_FAIL; + } + + if (!config) { + return POST_DEV_CFG_DONE; + }*/ + return POST_DEV_CFG_DONE; +} + +const Driver_fxnTable SI1141_fxnTable = { + /* Message handlers */ + .cb_probe = _probe, + .cb_init = _init, + .cb_get_status = _get_status, + //.cb_get_config = _get_config, + //.cb_set_config = _set_config, +}; diff --git a/firmware/ec/src/Devices/ocmp_wrappers/ocmp_slb9645.c b/firmware/ec/src/Devices/ocmp_wrappers/ocmp_slb9645.c new file mode 100644 index 0000000000..3407f2dca1 --- /dev/null +++ b/firmware/ec/src/Devices/ocmp_wrappers/ocmp_slb9645.c @@ -0,0 +1,24 @@ +/** + * Copyright (c) 2017-present, Facebook, Inc. + * All rights reserved. + * + * This source code is licensed under the BSD-style license found in the + * LICENSE file in the root directory of this source tree. An additional grant + * of patent rights can be found in the PATENTS file in the same directory. + */ + +#include "common/inc/ocmp_wrappers/ocmp_slb9645.h" +#include "common/inc/global/Framework.h" +#include "helpers/array.h" +#include "helpers/math.h" +#include "inc/devices/slb9645.h" + +static ePostCode _probe(void *driver, POSTData *postData) +{ + return slb9645_probe(driver,postData); +} + +const Driver_fxnTable SLB9645_fxnTable = { + /* Message handlers */ + .cb_probe = _probe, +}; diff --git a/firmware/ec/src/Devices/ocmp_wrappers/ocmp_syncio.c b/firmware/ec/src/Devices/ocmp_wrappers/ocmp_syncio.c new file mode 100644 index 0000000000..222e0b35cd --- /dev/null +++ b/firmware/ec/src/Devices/ocmp_wrappers/ocmp_syncio.c @@ -0,0 +1,19 @@ +/** + * Copyright (c) 2017-present, Facebook, Inc. + * All rights reserved. + * + * This source code is licensed under the BSD-style license found in the + * LICENSE file in the root directory of this source tree. An additional grant + * of patent rights can be found in the PATENTS file in the same directory. + */ +#include "common/inc/ocmp_wrappers/ocmp_syncio.h" + +#include "common/inc/global/Framework.h" +#include "inc/subsystem/sync/sync.h" + +const Driver_fxnTable SYNC_fxnTable = { + /* Message handlers */ + .cb_get_status = SYNC_GpsStatus, +}; + + diff --git a/firmware/ec/src/Devices/ocmp_wrappers/ocmp_testmodule.c b/firmware/ec/src/Devices/ocmp_wrappers/ocmp_testmodule.c new file mode 100644 index 0000000000..fe0d76e5e2 --- /dev/null +++ b/firmware/ec/src/Devices/ocmp_wrappers/ocmp_testmodule.c @@ -0,0 +1,112 @@ +/** + * Copyright (c) 2017-present, Facebook, Inc. + * All rights reserved. + * + * This source code is licensed under the BSD-style license found in the + * LICENSE file in the root directory of this source tree. An additional grant + * of patent rights can be found in the PATENTS file in the same directory. + */ +#include "common/inc/ocmp_wrappers/ocmp_testmodule.h" + +#include "inc/common/global_header.h" + +typedef enum { + TWOG_IMEI = 0, + TWOG_IMSI = 1, + TWOG_GETMFG = 2, + TWOG_GETMODEL = 3, + TWOG_RSSI = 4, + TWOG_BER = 5, + TWOG_REGSTATUS = 6, + TWOG_NETWORK_OP_INFO = 7, + TWOG_CELLID = 8, + TWOG_BSIC = 9, + TWOG_LASTERR = 10, + TWOG_PARAM_MAX /* Limiter */ +} eTestModule_StatusParam; + +static ePostCode _probe(void **driver) +{ + /* TODO: this is a problem: we can't probe until we've initialized, but we + * don't init until after probing */ + return POST_DEV_FOUND; +} + + +static ePostCode _init(void *driver, const void **config, + const void *alert_token) +{ + return g510_task_init(driver, config,alert_token); +} + +static bool _get_status(void *driver, unsigned int param_id, void *return_buf) +{ + bool ret = false; + switch (param_id) { + case TWOG_IMEI: + { + ret = g510_get_imei(return_buf); + break; + } + case TWOG_IMSI: + { + ret = g510_get_imsi(return_buf); + break; + } + case TWOG_GETMFG: + { + ret = g510_get_mfg(return_buf); + break; + } + case TWOG_GETMODEL: + { + ret = g510_get_model(return_buf); + break; + } + /* TODO: optimize this - no reason to call CSQ twice */ + case TWOG_RSSI: + { + ret = g510_get_rssi(return_buf); + break; + } + case TWOG_BER: + { + ret = g510_get_ber(return_buf); + break; + } + case TWOG_REGSTATUS: + { + ret = g510_get_regStatus(return_buf); + break; + } + case TWOG_NETWORK_OP_INFO: + /* TODO: from +COPS=? */ + return false; + case TWOG_CELLID: + { + ret = g510_get_cellId(return_buf); + break; + } + case TWOG_BSIC: + { + /* TODO: from +MCELL? */ + return false; + } + case TWOG_LASTERR: + { + /* TODO: implement last error */ + return false; + } + default: + LOGGER("TESTMOD::ERROR: Unknown param %d\n", param_id); + return false; + } + return ret; +} + +const Driver_fxnTable G510_fxnTable = { + /* Message handlers */ + .cb_probe = _probe, + .cb_init = _init, + .cb_get_status = _get_status, +};