I2C hang recover function added
Dependencies: UniGraphic mbed vt100
In this version, check_i2c_pins function was added in edge_mgr.cpp.
プログラムの起動時、I2Cモジュールを初期化する前に、I2Cに使用するピンの電位を確認し
もし一方でも Low に張り付いていた場合、SCL を GPIO 出力に設定して
所定回数 (I2C_UNLOCK_TRIAL_CYCLE) 反転させることにより、疑似リセットクロックを生成します。
その後は、通常の起動手順に復帰し、以降はこれまでと同様の動作をします。
af_utils/af_attriburtes.cpp
- Committer:
- Rhyme
- Date:
- 2018-04-03
- Revision:
- 0:d895cd1cd897
File content as of revision 0:d895cd1cd897:
#include "mbed.h" #include <ctype.h> #include "af_attributes.h" #include "edge_time.h" #include "edge_sensor.h" #include "edge_accel.h" #include "edge_color.h" #include "edge_temp.h" #include "edge_pressure.h" #include "edge_mgr.h" #include "edge_reset_mgr.h" // #include "SO1602A.h" #include <ILI9341.h> #include "pending.h" // extern SO1602A *display ; extern ILI9341 *display ; extern pending_class *pending ; static const af_attribute_type af_attr[] = { /* ID, Description, Type, Size */ { ATTR_SENSE_VAL, "Sensor Value", ATTRIBUTE_TYPE_UTF8S, 255 }, { ATTR_ACCEL_PRESENT, "Accel Present", ATTRIBUTE_TYPE_BOOLEAN, 1 }, { ATTR_ACCEL_ENABLE, "Accel Enable", ATTRIBUTE_TYPE_BOOLEAN, 1 }, { ATTR_ACCEL_INTERVAL, "Accel Interval", ATTRIBUTE_TYPE_SINT16, 2 }, { ATTR_ACCEL_VALUE, "Accel Value", ATTRIBUTE_TYPE_FIXED_15_16, 4}, /* first color sensor (VEML6040) and LED set */ { ATTR_COLOR0_PRESENT, "Color1 Present", ATTRIBUTE_TYPE_BOOLEAN, 1 }, { ATTR_COLOR0_ENABLE, "Color1 Enable", ATTRIBUTE_TYPE_BOOLEAN, 1 }, { ATTR_COLOR0_INTERVAL, "Color1 Interval", ATTRIBUTE_TYPE_SINT16, 2 }, { ATTR_COLOR0_TRIGMODE, "Color1 Trigger Mode", ATTRIBUTE_TYPE_SINT8, 1 }, { ATTR_COLOR0_ITIME, "Color1 Integration Time", ATTRIBUTE_TYPE_SINT8, 1 }, { ATTR_COLOR0_CALIBRATE, "Color1 Calibrate", ATTRIBUTE_TYPE_BOOLEAN, 1 }, { ATTR_COLOR0_PWM_R, "Color1 PWM R", ATTRIBUTE_TYPE_SINT32, 4 }, { ATTR_COLOR0_PWM_G, "Color1 PWM G", ATTRIBUTE_TYPE_SINT32, 4 }, { ATTR_COLOR0_PWM_B, "Color1 PWM B", ATTRIBUTE_TYPE_SINT32, 4 }, { ATTR_COLOR0_PWM_PERIOD, "Color1 PWM Period", ATTRIBUTE_TYPE_SINT16, 2 }, { ATTR_COLOR0_PWM_TARGET, "Color1 PWM Target", ATTRIBUTE_TYPE_SINT16, 2 }, { ATTR_COLOR0_R_VALUE, "Color1 R", ATTRIBUTE_TYPE_SINT16, 2 }, { ATTR_COLOR0_G_VALUE, "Color1 G", ATTRIBUTE_TYPE_SINT16, 2 }, { ATTR_COLOR0_B_VALUE, "Color1 B", ATTRIBUTE_TYPE_SINT16, 2 }, /* second color sensor (VEML6040) and LED set */ { ATTR_COLOR1_PRESENT, "Color2 Present", ATTRIBUTE_TYPE_BOOLEAN, 1 }, { ATTR_COLOR1_ENABLE, "Color2 Enable", ATTRIBUTE_TYPE_BOOLEAN, 1 }, { ATTR_COLOR1_INTERVAL, "Color2 Interval", ATTRIBUTE_TYPE_SINT16, 2 }, { ATTR_COLOR1_TRIGMODE, "Color2 Trigger Mode", ATTRIBUTE_TYPE_SINT8, 1 }, { ATTR_COLOR1_ITIME, "Color2 Integration Time", ATTRIBUTE_TYPE_SINT8, 1 }, { ATTR_COLOR1_CALIBRATE, "Color2 Calibrate", ATTRIBUTE_TYPE_BOOLEAN, 1 }, { ATTR_COLOR1_PWM_R, "Color2 PWM R", ATTRIBUTE_TYPE_SINT32, 4 }, { ATTR_COLOR1_PWM_G, "Color2 PWM G", ATTRIBUTE_TYPE_SINT32, 4 }, { ATTR_COLOR1_PWM_B, "Color2 PWM B", ATTRIBUTE_TYPE_SINT32, 4 }, { ATTR_COLOR1_PWM_PERIOD, "Color2 PWM Period", ATTRIBUTE_TYPE_SINT16, 2 }, { ATTR_COLOR1_PWM_TARGET, "Color2 PWM Target", ATTRIBUTE_TYPE_SINT16, 2 }, { ATTR_COLOR1_R_VALUE, "Color2 R", ATTRIBUTE_TYPE_SINT16, 2 }, { ATTR_COLOR1_G_VALUE, "Color2 G", ATTRIBUTE_TYPE_SINT16, 2 }, { ATTR_COLOR1_B_VALUE, "Color2 B", ATTRIBUTE_TYPE_SINT16, 2 }, /* first temperature sensor (LM75B) */ { ATTR_TEMP0_PRESENT, "Temp0 Present", ATTRIBUTE_TYPE_BOOLEAN, 1 }, { ATTR_TEMP0_ENABLE, "Temp0 Enable", ATTRIBUTE_TYPE_BOOLEAN, 1 }, { ATTR_TEMP0_INTERVAL, "Temp0 Interval", ATTRIBUTE_TYPE_SINT16, 2 }, { ATTR_TEMP0_VALUE, "Temp0 Value", ATTRIBUTE_TYPE_FIXED_15_16, 4}, /* second temperature sensor (SMTC502AT/Before) */ { ATTR_TEMP1_PRESENT, "Temp1 Present", ATTRIBUTE_TYPE_BOOLEAN, 1 }, { ATTR_TEMP1_ENABLE, "Temp1 Enable", ATTRIBUTE_TYPE_BOOLEAN, 1 }, { ATTR_TEMP1_INTERVAL, "Temp1 Interval", ATTRIBUTE_TYPE_SINT16, 2 }, { ATTR_TEMP1_VALUE, "Temp1 Value", ATTRIBUTE_TYPE_FIXED_15_16, 4}, /* third temperature sensor (SMTC502AT/After) */ { ATTR_TEMP2_PRESENT, "Temp2 Present", ATTRIBUTE_TYPE_BOOLEAN, 1 }, { ATTR_TEMP2_ENABLE, "Temp2 Enable", ATTRIBUTE_TYPE_BOOLEAN, 1 }, { ATTR_TEMP2_INTERVAL, "Temp2 Interval", ATTRIBUTE_TYPE_SINT16, 2 }, { ATTR_TEMP2_VALUE, "Temp2 Value", ATTRIBUTE_TYPE_FIXED_15_16, 4}, /* fouth temperateure sensor (LM75B) */ { ATTR_TEMP3_PRESENT, "Temp3 Present", ATTRIBUTE_TYPE_BOOLEAN, 1 }, { ATTR_TEMP3_ENABLE, "Temp3 Enable", ATTRIBUTE_TYPE_BOOLEAN, 1 }, { ATTR_TEMP3_INTERVAL, "Temp3 Interval", ATTRIBUTE_TYPE_SINT16, 2 }, { ATTR_TEMP3_VALUE, "Temp3 Value", ATTRIBUTE_TYPE_FIXED_15_16, 4}, /* Gas Pressure sensor (PSE530) */ { ATTR_GAS_PRESENT, "Gas Pressure Present", ATTRIBUTE_TYPE_BOOLEAN, 1 }, { ATTR_GAS_ENABLE, "Gas Pressure Enable", ATTRIBUTE_TYPE_BOOLEAN, 1 }, { ATTR_GAS_INTERVAL, "Gas Pressure Interval", ATTRIBUTE_TYPE_SINT16, 2 }, { ATTR_GAS_VALUE, "Gas Pressure Value", ATTRIBUTE_TYPE_FIXED_15_16, 4}, { ATTR_GAS_THR_MODE, "Gas Press Threshold Mode", ATTRIBUTE_TYPE_SINT8, 1 }, { ATTR_GAS_THR_HIGH, "Gas Press High Thresh", ATTRIBUTE_TYPE_SINT16, 2 }, { ATTR_GAS_THR_LOW, "Gas Press Low Thresh", ATTRIBUTE_TYPE_SINT16, 2 }, /* Software Reset Request */ { ATTR_SOFTWARE_RESET, "Software Reset", ATTRIBUTE_TYPE_BOOLEAN, 1 }, { ATTR_DISPLAY_MODE, "Display Mode", ATTRIBUTE_TYPE_SINT8, 1 }, { ATTR_MCU_RESET_REASON, "MCU Reset Reason", ATTRIBUTE_TYPE_UTF8S, 64 }, { ATTR_LED, "LED", ATTRIBUTE_TYPE_SINT16, 2 }, { ATTR_IO0, "I/O 0", ATTRIBUTE_TYPE_SINT64, 8 }, { ATTR_IO1, "I/O 1", ATTRIBUTE_TYPE_SINT64, 8 }, { ATTR_IO2, "I/O 2", ATTRIBUTE_TYPE_SINT64, 8 }, { ATTR_BUTTON, "BUTTON", ATTRIBUTE_TYPE_BOOLEAN, 2 }, { ATTR_IO3, "I/O 3", ATTRIBUTE_TYPE_SINT64, 8 }, { ATTR_BOOT_LOADER_VER, "Bootloader Version", ATTRIBUTE_TYPE_SINT64, 8 }, { ATTR_BLE_STACK_VER, "BLE Stack Version", ATTRIBUTE_TYPE_SINT64, 8 }, { ATTR_FW_APP_VER, "FW Application Version", ATTRIBUTE_TYPE_SINT64, 8 }, { ATTR_DEVICE_DESC, "Device Description", ATTRIBUTE_TYPE_SINT64, 8 }, { ATTR_WIFI_VER, "Wi-Fi chip", ATTRIBUTE_TYPE_SINT64, 8 }, { ATTR_OFFLINE_SCHED, "Offline Schedules enable", ATTRIBUTE_TYPE_SINT16, 2 }, { ATTR_SECURITY_ENABLED, "Security Enabled", ATTRIBUTE_TYPE_SINT8, 1 }, /* ? */ { ATTR_UTC_OFFSET, "UTC offset data", ATTRIBUTE_TYPE_BYTES, 8 }, { ATTR_CONFIGURES_SSID, "Configured SSID", ATTRIBUTE_TYPE_UTF8S, 10 }, /* ? */ { ATTR_WIFI_BARS, "Wi-Fi Bars", ATTRIBUTE_TYPE_SINT8, 1 }, { ATTR_WIFI_STDY_STATE, "Wi-Fi Steady State", ATTRIBUTE_TYPE_SINT8, 1 }, { ATTR_COMMAND, "Command", ATTRIBUTE_TYPE_BYTES, 8 }, /* ? */ { ATTR_ASR_STATE, "ASR State", ATTRIBUTE_TYPE_SINT8, 1 }, { ATTR_LOW_BATTERY, "Low Battery Warning", ATTRIBUTE_TYPE_SINT8, 1 }, { ATTR_LINKED_TIMESTAMP, "Linked Timestamp", ATTRIBUTE_TYPE_SINT32, 4 }, { ATTR_ATTR_ACK, "Attribute ACK", ATTRIBUTE_TYPE_SINT16, 8 }, { ATTR_REBOOT_REASON, "Reboot Reason", ATTRIBUTE_TYPE_UTF8S, 100 }, { ATTR_BLE_COMMS, "BLE Comms", ATTRIBUTE_TYPE_BYTES, 12 }, { ATTR_MCU_INTERFACE, "MCU Interface", ATTRIBUTE_TYPE_SINT8, 1 }, { 0, 0, 0, 0 } } ; int get_af_attr(uint16_t id) { int i ; for (i = 0 ; af_attr[i].id != 0 ; i++ ) { if (id == af_attr[i].id) { break ; } } return (i) ; } void print_af_error(int resultCode) { switch(resultCode) { case afSUCCESS: printf("Operation completed successfully\n") ; break ; case afERROR_NO_SUCH_ATTRIBUTE: printf("Request was made for unknown attribute id\n") ; break ; case afERROR_BUSY: printf("Request already in progress, try again\n") ; break ; case afERROR_INVALID_COMMAND: printf("Command could not be parsed\n") ; break ; case afERROR_QUEUE_OVERFLOW: printf("Queue is full\n") ; break ; case afERROR_QUEUE_UNDERFLOW: printf("Queue is empty\n") ; break ; case afERROR_INVALID_PARAM: printf("Bad input parameter\n") ; break ; default: printf("Unknown error code %d\n", resultCode) ; break ; } } void af_print_values( const uint8_t requestId, const uint16_t attributeId, const uint16_t valueLen, const uint8_t *value ) { int i, id ; id = get_af_attr(attributeId) ; if (af_attr[id].id != 0) { printf(af_attr[id].description) ; printf(" : ") ; switch(af_attr[id].attribute_type) { case ATTRIBUTE_TYPE_BOOLEAN: case ATTRIBUTE_TYPE_SINT8: if (valueLen >= 1) { printf("%02X\n", value[0]) ; } break ; case ATTRIBUTE_TYPE_SINT16: if (valueLen >= 2) { printf("%02X%02X\n", value[1], value[0]) ; } break ; case ATTRIBUTE_TYPE_SINT32: if (valueLen >= 4) { printf("%02X%02X%02X%02X\n", value[3],value[2],value[1],value[0]) ; } break ; case ATTRIBUTE_TYPE_SINT64: if (valueLen >= 8) { printf("%02X%02X %02X%02X %02X%02X %02X%02X\n", value[7], value[6], value[5], value[4], value[3], value[2], value[1], value[0]) ; } break ; case ATTRIBUTE_TYPE_UTF8S: if (valueLen > 0) { for (i = 0 ; i < valueLen ; i++) { if (isprint(value[i])) { printf("%c", value[i]) ; } else if (value[i] == 0) { /* string terminator NULL */ break ; } else { printf("\'%02X\'",value[i]) ; } } printf("\n") ; } break ; case ATTRIBUTE_TYPE_BYTES: default: if (valueLen > 0) { for (i = 0 ; i < valueLen ; i++ ) { printf("%02X ", value[i]) ; } printf("\n") ; } break ; } } else { if (valueLen > 0) { for (i = 0 ; i < valueLen ; i++ ) { printf("%02X ", value[i]) ; } printf("\n") ; } } // printf("\n") ; } void assignAttribute( const uint8_t requestId, const uint16_t attributeId, const uint16_t valueLen, const uint8_t *value, bool fromRequest ) { switch(attributeId) { case ATTR_LINKED_TIMESTAMP: /* timestamp */ set_time(valueLen, value) ; /* 68 us */ if (fromRequest) afero->setAttributeComplete(requestId, attributeId, valueLen, value) ; printf("timestampe = ") ; print_date_wd(¤t_time) ; // print_time(¤t_time) ; printf("\n") ; break ; case ATTR_SOFTWARE_RESET: /* software reset requested! */ if (value[0]) { reset_watch_dog() ; printf("Software Reset Requested!\n") ; if (display != 0) { display->cls() ; display->locate(0,0) ; display->printf("System Rebooting!") ; } reset_watch_dog() ; if (fromRequest) afero->setAttributeComplete(requestId, attributeId, valueLen, value) ; wait(0.5) ; reset_watch_dog() ; reboot_edge() ; } break ; case ATTR_DISPLAY_MODE: if (display_mode != value[0]) { display_mode = value[0] ; if (display) { display->BusEnable(true) ; display->cls() ; display->BusEnable(false) ; } } reset_watch_dog() ; switch(value[0]) { case DISPLAY_MODE_GAS: /* gas pressure monitor only */ break ; case DISPLAY_MODE_SUMMARY: /* summary */ break ; case DISPLAY_MODE_CHART: /* chart mode */ if (display) { draw_all_chart_frame() ; } break ; case DISPLAY_MODE_OFF: /* display off */ default: display_mode = DISPLAY_MODE_OFF ; break ; } if (fromRequest) afero->setAttributeComplete(requestId, attributeId, valueLen, value) ; break ; case ATTR_ACCEL_ENABLE: /* accel enable */ if (sensor[SENSOR_ID_ACCEL]) { if (value[0]) { sensor[SENSOR_ID_ACCEL]->reset() ; sensor[SENSOR_ID_ACCEL]->enable() ; } else if (sensor[SENSOR_ID_ACCEL]){ sensor[SENSOR_ID_ACCEL]->disable() ; } if (fromRequest) afero->setAttributeComplete(requestId, attributeId, valueLen, value) ; } break ; case ATTR_ACCEL_INTERVAL: if (sensor[SENSOR_ID_ACCEL]) { sensor[SENSOR_ID_ACCEL]->setInterval((value[1] << 8) | value[0]) ; if (fromRequest) afero->setAttributeComplete(requestId, attributeId, valueLen, value) ; } break ; case ATTR_COLOR0_ENABLE: /* color0 enable */ if (sensor[SENSOR_ID_COLOR1]) { if (value[0]) { sensor[SENSOR_ID_COLOR1]->reset() ; sensor[SENSOR_ID_COLOR1]->enable() ; } else { sensor[SENSOR_ID_COLOR1]->disable() ; } if (fromRequest) afero->setAttributeComplete(requestId, attributeId, valueLen, value) ; } break ; case ATTR_COLOR0_INTERVAL: if (sensor[SENSOR_ID_COLOR1]) { sensor[SENSOR_ID_COLOR1]->setInterval((value[1] << 8) | value[0]) ; if (fromRequest) afero->setAttributeComplete(requestId, attributeId, valueLen, value) ; } break ; case ATTR_COLOR0_TRIGMODE: /* color0 config */ if (sensor[SENSOR_ID_COLOR1]) { uint8_t config = ((edge_color*)sensor[SENSOR_ID_COLOR1])->getConfig() & 0x70 ; if (value[0]) { config = config | 0x06 ; } ((edge_color*)sensor[SENSOR_ID_COLOR1])->setConfig(config) ; if (fromRequest) afero->setAttributeComplete(requestId, attributeId, valueLen, value) ; } break ; case ATTR_COLOR0_ITIME: /* color0 config */ if (sensor[SENSOR_ID_COLOR1]) { uint8_t config = ((edge_color*)sensor[SENSOR_ID_COLOR1])->getConfig() & 0x07 ; config = (value[0] << 4) | config ; ((edge_color*)sensor[SENSOR_ID_COLOR1])->setConfig(config) ; if (fromRequest) afero->setAttributeComplete(requestId, attributeId, valueLen, value) ; } break ; case ATTR_COLOR0_PWM_PERIOD: /* color0 pwm period */ if (sensor[SENSOR_ID_COLOR1]) { ((edge_color*)sensor[SENSOR_ID_COLOR1])->set_pwm_period((value[1] << 8) | value[0]) ; if (fromRequest) afero->setAttributeComplete(requestId, attributeId, valueLen, value) ; } break ; case ATTR_COLOR0_PWM_TARGET: /* color0 pwm calibration target */ if (sensor[SENSOR_ID_COLOR1]) { color0_target[0] = (value[1] << 8) | value[0] ; color0_target[1] = color0_target[0] ; color0_target[2] = color0_target[1] ; if (fromRequest) afero->setAttributeComplete(requestId, attributeId, valueLen, value) ; } break ; #if 1 /* do not handle calibration twice */ case ATTR_COLOR0_CALIBRATE: /* calibrate color0 */ if (sensor[SENSOR_ID_COLOR1] && value[0] && fromRequest) { /* do calibration */ ((edge_color*)sensor[SENSOR_ID_COLOR1])->request_calibration() ; } break ; #endif case ATTR_COLOR0_PWM_R: if (sensor[SENSOR_ID_COLOR1]) { ((edge_color*)sensor[SENSOR_ID_COLOR1])->setPwmR( (value[1] << 8) | value[0] ) ; // color0_pwm[0] = (value[1] << 8) | value[0] ; } if (fromRequest) afero->setAttributeComplete(requestId, attributeId, valueLen, value) ; break ; case ATTR_COLOR0_PWM_G: if (sensor[SENSOR_ID_COLOR1]) { ((edge_color*)sensor[SENSOR_ID_COLOR1])->setPwmG( (value[1] << 8) | value[0] ) ; // color0_pwm[1] = (value[1] << 8) | value[0] ; } if (fromRequest) afero->setAttributeComplete(requestId, attributeId, valueLen, value) ; break ; case ATTR_COLOR0_PWM_B: if (sensor[SENSOR_ID_COLOR1]) { ((edge_color*)sensor[SENSOR_ID_COLOR1])->setPwmB( (value[1] << 8) | value[0] ) ; // color0_pwm[2] = (value[1] << 8) | value[0] ; } if (fromRequest) afero->setAttributeComplete(requestId, attributeId, valueLen, value) ; break ; case ATTR_COLOR1_ENABLE: /* color1 enable */ if (sensor[SENSOR_ID_COLOR2]) { if (value[0]) { sensor[SENSOR_ID_COLOR2]->reset() ; sensor[SENSOR_ID_COLOR2]->enable() ; } else { sensor[SENSOR_ID_COLOR2]->disable() ; } if (fromRequest) afero->setAttributeComplete(requestId, attributeId, valueLen, value) ; } break ; case ATTR_COLOR1_INTERVAL: if (sensor[SENSOR_ID_COLOR2]) { sensor[SENSOR_ID_COLOR2]->setInterval((value[1] << 8) | value[0]) ; if (fromRequest) afero->setAttributeComplete(requestId, attributeId, valueLen, value) ; } break ; case ATTR_COLOR1_TRIGMODE: /* color0 config */ if (sensor[SENSOR_ID_COLOR2]) { uint8_t config = ((edge_color*)sensor[SENSOR_ID_COLOR2])->getConfig() & 0x70 ; if (value[0]) { config = config | 0x06 ; } ((edge_color*)sensor[SENSOR_ID_COLOR2])->setConfig(config) ; if (fromRequest) afero->setAttributeComplete(requestId, attributeId, valueLen, value) ; } break ; case ATTR_COLOR1_ITIME: /* color0 config */ if (sensor[SENSOR_ID_COLOR2]) { uint8_t config = ((edge_color*)sensor[SENSOR_ID_COLOR2])->getConfig() & 0x07 ; config = (value[0] << 4) | config ; ((edge_color*)sensor[SENSOR_ID_COLOR2])->setConfig(config) ; if (fromRequest) afero->setAttributeComplete(requestId, attributeId, valueLen, value) ; } break ; case ATTR_COLOR1_PWM_PERIOD: /* color0 pwm period */ if (sensor[SENSOR_ID_COLOR2]) { ((edge_color*)sensor[SENSOR_ID_COLOR2])->set_pwm_period((value[1] << 8) | value[0]) ; if (fromRequest) afero->setAttributeComplete(requestId, attributeId, valueLen, value) ; } break ; case ATTR_COLOR1_PWM_TARGET: /* color0 pwm calibration target */ if (sensor[SENSOR_ID_COLOR2]) { color1_target[0] = (value[1] << 8) | value[0] ; color1_target[1] = color1_target[0] ; color1_target[2] = color1_target[1] ; if (fromRequest) afero->setAttributeComplete(requestId, attributeId, valueLen, value) ; } break ; #if 1 /* do not handle calibration twice */ case ATTR_COLOR1_CALIBRATE: /* calibrate color1 */ if (sensor[SENSOR_ID_COLOR2] && value[0] && fromRequest) { /* do calibration! */ ((edge_color*)sensor[SENSOR_ID_COLOR2])->request_calibration() ; } break ; #endif case ATTR_COLOR1_PWM_R: if (sensor[SENSOR_ID_COLOR2]) { ((edge_color*)sensor[SENSOR_ID_COLOR2])->setPwmR( (value[1] << 8) | value[0] ) ; // color1_pwm[0] = (value[1] << 8) | value[0] ; } if (fromRequest) afero->setAttributeComplete(requestId, attributeId, valueLen, value) ; break ; case ATTR_COLOR1_PWM_G: if (sensor[SENSOR_ID_COLOR2]) { ((edge_color*)sensor[SENSOR_ID_COLOR2])->setPwmG( (value[1] << 8) | value[0] ) ; // color1_pwm[1] = (value[1] << 8) | value[0] ; } if (fromRequest) afero->setAttributeComplete(requestId, attributeId, valueLen, value) ; break ; case ATTR_COLOR1_PWM_B: if (sensor[SENSOR_ID_COLOR2]) { ((edge_color*)sensor[SENSOR_ID_COLOR2])->setPwmB( (value[1] << 8) | value[0] ) ; // color1_pwm[2] = (value[1] << 8) | value[0] ; } if (fromRequest) afero->setAttributeComplete(requestId, attributeId, valueLen, value) ; break ; case ATTR_TEMP0_ENABLE: /* temp0 is used to control temp-sensors */ if (sensor[SENSOR_ID_TEMP]) { if (value[0]) { sensor[SENSOR_ID_TEMP]->reset() ; sensor[SENSOR_ID_TEMP]->enable() ; } else { sensor[SENSOR_ID_TEMP]->disable() ; } if (fromRequest) afero->setAttributeComplete(requestId, attributeId, valueLen, value) ; } break ; case ATTR_TEMP0_INTERVAL: if (sensor[SENSOR_ID_TEMP]) { sensor[SENSOR_ID_TEMP]->setInterval((value[1] << 8) | value[0]) ; if (fromRequest) afero->setAttributeComplete(requestId, attributeId, valueLen, value) ; } break ; case ATTR_TEMP3_ENABLE: /* temp3 enable */ break ; case ATTR_GAS_ENABLE: /* pressure enable */ if (sensor[SENSOR_ID_PRESS]) { if (value[0]) { sensor[SENSOR_ID_PRESS]->reset() ; sensor[SENSOR_ID_PRESS]->enable() ; } else { sensor[SENSOR_ID_PRESS]->disable() ; } if (fromRequest) afero->setAttributeComplete(requestId, attributeId, valueLen, value) ; } break ; case ATTR_GAS_INTERVAL: if (sensor[SENSOR_ID_PRESS]) { sensor[SENSOR_ID_PRESS]->setInterval((value[1] << 8) | value[0]) ; if (fromRequest) afero->setAttributeComplete(requestId, attributeId, valueLen, value) ; } break ; case ATTR_GAS_THR_MODE: if (sensor[SENSOR_ID_PRESS]) { ((edge_pressure*)sensor[SENSOR_ID_PRESS])->set_thr_mode(value[0]) ; if (fromRequest) afero->setAttributeComplete(requestId, attributeId, valueLen, value) ; } break ; case ATTR_GAS_THR_HIGH: if (sensor[SENSOR_ID_PRESS]) { ((edge_pressure*)sensor[SENSOR_ID_PRESS])->set_thr_high((value[1] << 8) | value[0]) ; if (fromRequest) afero->setAttributeComplete(requestId, attributeId, valueLen, value) ; } break ; case ATTR_GAS_THR_LOW: if (sensor[SENSOR_ID_PRESS]) { ((edge_pressure*)sensor[SENSOR_ID_PRESS])->set_thr_low((value[1] << 8) | value[0]) ; if (fromRequest) afero->setAttributeComplete(requestId, attributeId, valueLen, value) ; } break ; default: break ; } } /* * Callback that allows ASR to request an MCU attribute be changed. * You should define this function in your MCU firmware to perform application-specific actions * your code must take (e.g., updating the state of the hardware), * in light of the attribute value change. */ void attributeChangeRequest( const uint8_t requestId, const uint16_t attributeId, const uint16_t valueLen, const uint8_t *value ) { uint32_t timestamp = edge_time ; if ((pending != 0)&&(pending->request->requestId == requestId)) { pending->replied_time = timestamp ; } ts2time(timestamp, ¤t_time) ; /* 12 us */ if (verbos) { print_time(¤t_time) ; printf(" %5d ASR requested [%d] : ", attributeId, requestId) ; af_print_values(requestId, attributeId, valueLen, value) ; } assignAttribute(requestId, attributeId, valueLen, value, true) ; // af_print_values(requestId, attributeId, valueLen, value) ; if ((pending != 0)&&(pending->request->requestId == requestId)) { printf("Request [%d] replied in %d sec!\n", requestId, pending->replied_time - pending->submit_time) ; delete pending ; pending = 0 ; } } /* * Application callback that allows afLib to notify that an attribute has changed. * This method will be called in response to a getAttribute call from the application * and whenever a ASR module attribute changes. */ void attributeUpdatedReport( const uint8_t requestId, const uint16_t attributeId, const uint16_t valueLen, const uint8_t *value ) { uint32_t timestamp = edge_time ; int result ; if ((pending != 0)&&(pending->request->requestId == requestId)) { pending->replied_time = timestamp ; } ts2time(timestamp, ¤t_time) ; /* 12us */ if (verbos) { print_time(¤t_time) ; printf(" %5d ASR reported [%d]: ", attributeId, requestId) ; af_print_values(requestId, attributeId, valueLen, value) ; } switch(attributeId) { case ATTR_LINKED_TIMESTAMP: set_time(valueLen, value) ; /* 68 us */ printf("timestampe = ") ; print_date_wd(¤t_time) ; // print_time(¤t_time) ; printf("\n") ; break ; case ATTR_WIFI_STDY_STATE: gConnected = false ; printf("WiFi Steady State: ") ; switch(value[0]) { case 0: printf("Not Connected\n") ; break ; case 1: printf("Pending\n") ; break ; case 2: printf("Connected\n") ; gConnected = true ; // the only case Connected state is OK break ; case 3: printf("Unknown Failure\n") ; break ; case 4: printf("Association Failed\n") ; break ; case 5: printf("Handshake Failed\n") ; break ; case 6: printf("Echo Failed\n") ; break ; case 7: printf("SSID Not Found\n") ; break ; case 8: printf("NTP Failed\n") ; break ; default: printf("Unknown [%d]\n", value[0]) ; break ; } break ; case ATTR_REBOOT_REASON: printf("Reboot Reason: ") ; switch(value[0]) { case 1: printf("Reset pin asserted\n") ; break ; case 2: printf("Watchdog reset\n") ; break ; case 4: printf("Software reset\n") ; break ; case 8: printf("CPU Lock up\n") ; break ; default: printf("Unknown [%d]\n", value[0]) ; break ; } if (reboot_requested) { printf("Unexpected ASR Reboot. Rebooting MCU.\n") ; wait_ms(100) ; reboot_edge() ; } break ; case ATTR_MCU_INTERFACE: printf("MCU Interface: ") ; switch(value[0]) { case 0: printf("No MCU\n") ; break ; case 1: printf("SPI Slave\n") ; break ; case 2: printf("UART\n") ; break ; default: printf("Unknown\n") ; break ; } break ; case AF_SYSTEM_ASR_STATE: printf("ASR state: ") ; switch(value[0]) { case MODULE_STATE_REBOOTED: gLinked = false ; printf("Rebooted\n") ; // wait_ms(100) ; /* */ if (edge_mgr_status == EDGE_MGR_RUNNING) { result = afero->getAttribute(ATTR_REBOOT_REASON) ; reboot_requested = true ; // reboot_edge() ; } break ; case MODULE_STATE_LINKED: if (gLinked == false) { /* new link established */ result = afero->getAttribute(ATTR_LINKED_TIMESTAMP) ; if (result != afSUCCESS) { printf("getAttriute for ATTR_LINKED_TIMESTAMP failed\n") ; } } gLinked = true ; printf("Linked\n") ; break ; case MODULE_STATE_UPDATING: gLinked = true ; printf("Updating\n") ; if (display) { display->cls() ; display->locate(5, 5) ; display->printf("FW Updating...") ; } break ; case MOUDLE_STATE_UPDATE_READY: gLinked = false ; printf("Update ready - rebooting\n") ; if (display) { display->cls() ; display->locate(5, 5) ; display->printf("Rebooting...") ; } while(afero->setAttribute32(AF_SYSTEM_COMMAND, MODULE_COMMAND_REBOOT) != afSUCCESS) { afero->loop() ; wait_us(100) ; } reboot_edge() ; break ; default: break ; } break ; default: assignAttribute(requestId, attributeId, valueLen, value, false) ; break ; } if ((pending != 0)&&(pending->request->requestId == requestId)) { printf("Request [%d] replied in %d sec!\n", requestId, pending->replied_time - pending->submit_time) ; delete pending ; pending = 0 ; } }