From e86bede45fded3ca27c519da2568323d08f77fd5 Mon Sep 17 00:00:00 2001 From: strawmanbobi Date: Sun, 3 Dec 2017 16:45:37 +0800 Subject: [PATCH] modified example accordingto latest version of irext-core --- .../Application/Irext/include/ir_ac_apply.h | 10 +- .../Application/Irext/include/ir_ac_control.h | 190 ++++++++--------- .../include/ir_ac_parse_forbidden_info.h | 2 +- .../Irext/include/ir_ac_parse_parameter.h | 32 +-- .../Application/Irext/include/ir_decode.h | 2 +- .../Application/Irext/include/ir_tv_control.h | 17 +- .../Application/Irext/include/ir_utils.h | 6 +- .../Application/Irext/src/ir_ac_apply.c | 88 ++++---- .../Irext/src/ir_ac_binary_parse.c | 2 +- .../Application/Irext/src/ir_ac_build_frame.c | 22 +- .../Application/Irext/src/ir_ac_control.c | 22 +- .../Irext/src/ir_ac_parse_forbidden_info.c | 22 +- .../Irext/src/ir_ac_parse_frame_info.c | 54 ++--- .../Irext/src/ir_ac_parse_parameter.c | 98 ++++----- .../Source/Application/Irext/src/ir_decode.c | 22 +- .../Application/Irext/src/ir_tv_control.c | 41 ++-- .../Source/Application/Irext/src/ir_utils.c | 6 +- .../Source/Application/simpleBLEPeripheral.c | 18 +- pi3-smart-remote/.idea/misc.xml | 12 +- pi3-smart-remote/app/build.gradle | 3 +- .../app/src/main/AndroidManifest.xml | 2 +- .../net/irext/pi3sr/Pi3SRApplication.java | 13 ++ .../java/net/irext/pi3sr/driver/HCSR501.java | 63 ++++++ .../net/irext/pi3sr/driver/MotionSensor.java | 19 ++ .../irext/pi3sr/{ => ui}/MainActivity.java | 10 +- .../app/src/main/res/layout/activity_main.xml | 2 +- pi3-smart-remote/build.gradle | 2 +- .../gradle/wrapper/gradle-wrapper.properties | 4 +- .../BUILD_NUMBER | 1 + .../FindAndroidThings.cmake | 105 +++++++++ .../LICENSE | 201 ++++++++++++++++++ .../README.md | 47 ++++ .../armeabi-v7a/include/pio/gpio.h | 107 ++++++++++ .../armeabi-v7a/include/pio/i2c_device.h | 109 ++++++++++ .../armeabi-v7a/include/pio/i2s_device.h | 104 +++++++++ .../include/pio/peripheral_manager_client.h | 169 +++++++++++++++ .../armeabi-v7a/include/pio/pwm.h | 59 +++++ .../armeabi-v7a/include/pio/spi_device.h | 119 +++++++++++ .../armeabi-v7a/include/pio/uart_device.h | 178 ++++++++++++++++ .../armeabi-v7a/lib/libandroidthings.so | Bin 0 -> 137764 bytes .../x86/include/pio/gpio.h | 107 ++++++++++ .../x86/include/pio/i2c_device.h | 109 ++++++++++ .../x86/include/pio/i2s_device.h | 104 +++++++++ .../include/pio/peripheral_manager_client.h | 169 +++++++++++++++ .../x86/include/pio/pwm.h | 59 +++++ .../x86/include/pio/spi_device.h | 119 +++++++++++ .../x86/include/pio/uart_device.h | 178 ++++++++++++++++ .../x86/lib/libandroidthings.so | Bin 0 -> 190916 bytes 48 files changed, 2479 insertions(+), 349 deletions(-) create mode 100644 pi3-smart-remote/app/src/main/java/net/irext/pi3sr/Pi3SRApplication.java create mode 100644 pi3-smart-remote/app/src/main/java/net/irext/pi3sr/driver/HCSR501.java create mode 100644 pi3-smart-remote/app/src/main/java/net/irext/pi3sr/driver/MotionSensor.java rename pi3-smart-remote/app/src/main/java/net/irext/pi3sr/{ => ui}/MainActivity.java (71%) create mode 100644 pi3-smart-remote/native-libandroidthings-0.5.1-devpreview/BUILD_NUMBER create mode 100644 pi3-smart-remote/native-libandroidthings-0.5.1-devpreview/FindAndroidThings.cmake create mode 100644 pi3-smart-remote/native-libandroidthings-0.5.1-devpreview/LICENSE create mode 100644 pi3-smart-remote/native-libandroidthings-0.5.1-devpreview/README.md create mode 100644 pi3-smart-remote/native-libandroidthings-0.5.1-devpreview/armeabi-v7a/include/pio/gpio.h create mode 100644 pi3-smart-remote/native-libandroidthings-0.5.1-devpreview/armeabi-v7a/include/pio/i2c_device.h create mode 100644 pi3-smart-remote/native-libandroidthings-0.5.1-devpreview/armeabi-v7a/include/pio/i2s_device.h create mode 100644 pi3-smart-remote/native-libandroidthings-0.5.1-devpreview/armeabi-v7a/include/pio/peripheral_manager_client.h create mode 100644 pi3-smart-remote/native-libandroidthings-0.5.1-devpreview/armeabi-v7a/include/pio/pwm.h create mode 100644 pi3-smart-remote/native-libandroidthings-0.5.1-devpreview/armeabi-v7a/include/pio/spi_device.h create mode 100644 pi3-smart-remote/native-libandroidthings-0.5.1-devpreview/armeabi-v7a/include/pio/uart_device.h create mode 100644 pi3-smart-remote/native-libandroidthings-0.5.1-devpreview/armeabi-v7a/lib/libandroidthings.so create mode 100644 pi3-smart-remote/native-libandroidthings-0.5.1-devpreview/x86/include/pio/gpio.h create mode 100644 pi3-smart-remote/native-libandroidthings-0.5.1-devpreview/x86/include/pio/i2c_device.h create mode 100644 pi3-smart-remote/native-libandroidthings-0.5.1-devpreview/x86/include/pio/i2s_device.h create mode 100644 pi3-smart-remote/native-libandroidthings-0.5.1-devpreview/x86/include/pio/peripheral_manager_client.h create mode 100644 pi3-smart-remote/native-libandroidthings-0.5.1-devpreview/x86/include/pio/pwm.h create mode 100644 pi3-smart-remote/native-libandroidthings-0.5.1-devpreview/x86/include/pio/spi_device.h create mode 100644 pi3-smart-remote/native-libandroidthings-0.5.1-devpreview/x86/include/pio/uart_device.h create mode 100644 pi3-smart-remote/native-libandroidthings-0.5.1-devpreview/x86/lib/libandroidthings.so diff --git a/cc26xx-example/ti/BLE-CC264x/ble_cc26xx/Projects/ble/SimpleBLEPeripheral-IREXT/CC26xx/Source/Application/Irext/include/ir_ac_apply.h b/cc26xx-example/ti/BLE-CC264x/ble_cc26xx/Projects/ble/SimpleBLEPeripheral-IREXT/CC26xx/Source/Application/Irext/include/ir_ac_apply.h index 4c3db32..a9dc4d2 100644 --- a/cc26xx-example/ti/BLE-CC264x/ble_cc26xx/Projects/ble/SimpleBLEPeripheral-IREXT/CC26xx/Source/Application/Irext/include/ir_ac_apply.h +++ b/cc26xx-example/ti/BLE-CC264x/ble_cc26xx/Projects/ble/SimpleBLEPeripheral-IREXT/CC26xx/Source/Application/Irext/include/ir_ac_apply.h @@ -22,15 +22,15 @@ extern "C" #define MIN_TAG_LENGTH_TYPE_1 4 #define MIN_TAG_LENGTH_TYPE_2 6 -INT8 apply_power(remote_ac_status_t ac_status, UINT8 function_code); +INT8 apply_power(t_remote_ac_status ac_status, UINT8 function_code); -INT8 apply_mode(remote_ac_status_t ac_status, UINT8 function_code); +INT8 apply_mode(t_remote_ac_status ac_status, UINT8 function_code); -INT8 apply_wind_speed(remote_ac_status_t ac_status, UINT8 function_code); +INT8 apply_wind_speed(t_remote_ac_status ac_status, UINT8 function_code); -INT8 apply_swing(remote_ac_status_t ac_status, UINT8 function_code); +INT8 apply_swing(t_remote_ac_status ac_status, UINT8 function_code); -INT8 apply_temperature(remote_ac_status_t ac_status, UINT8 function_code); +INT8 apply_temperature(t_remote_ac_status ac_status, UINT8 function_code); INT8 apply_function(struct ac_protocol *protocol, UINT8 function); diff --git a/cc26xx-example/ti/BLE-CC264x/ble_cc26xx/Projects/ble/SimpleBLEPeripheral-IREXT/CC26xx/Source/Application/Irext/include/ir_ac_control.h b/cc26xx-example/ti/BLE-CC264x/ble_cc26xx/Projects/ble/SimpleBLEPeripheral-IREXT/CC26xx/Source/Application/Irext/include/ir_ac_control.h index 6d297c0..6eeee04 100644 --- a/cc26xx-example/ti/BLE-CC264x/ble_cc26xx/Projects/ble/SimpleBLEPeripheral-IREXT/CC26xx/Source/Application/Irext/include/ir_ac_control.h +++ b/cc26xx-example/ti/BLE-CC264x/ble_cc26xx/Projects/ble/SimpleBLEPeripheral-IREXT/CC26xx/Source/Application/Irext/include/ir_ac_control.h @@ -19,22 +19,22 @@ extern "C" #include "ir_defs.h" -#define TAG_COUNT_FOR_PROTOCOL 29 +#define TAG_COUNT_FOR_PROTOCOL 29 -#define TAG_INVALID 0xffff +#define TAG_INVALID 0xffff -#define MAX_DELAYCODE_NUM 16 -#define MAX_BITNUM 16 +#define MAX_DELAYCODE_NUM 16 +#define MAX_BITNUM 16 -#define AC_PARAMETER_TYPE_1 0 -#define AC_PARAMETER_TYPE_2 1 +#define AC_PARAMETER_TYPE_1 0 +#define AC_PARAMETER_TYPE_2 1 typedef enum { AC_POWER_ON = 0, AC_POWER_OFF, AC_POWER_MAX -} ac_power; +} t_ac_power; typedef enum { @@ -54,7 +54,7 @@ typedef enum AC_TEMP_29, AC_TEMP_30, AC_TEMP_MAX -} ac_temperature; +} t_ac_temperature; typedef enum { @@ -64,7 +64,7 @@ typedef enum AC_MODE_FAN, AC_MODE_DRY, AC_MODE_MAX -} ac_mode; +} t_ac_mode; typedef enum { @@ -76,7 +76,7 @@ typedef enum AC_FUNCTION_WIND_SWING, AC_FUNCTION_WIND_FIX, AC_FUNCTION_MAX, -} ac_function; +} t_ac_function; typedef enum { @@ -85,14 +85,14 @@ typedef enum AC_WS_MEDIUM, AC_WS_HIGH, AC_WS_MAX -} ac_wind_speed; +} t_ac_wind_speed; typedef enum { AC_SWING_ON = 0, AC_SWING_OFF, AC_SWING_MAX -} ac_swing; +} t_ac_swing; typedef enum { @@ -107,7 +107,7 @@ typedef enum TEMP_TYPE_DYNAMIC = 0, TEMP_TYPE_STATIC, TEMP_TYPE_MAX, -} temp_type; +} t_temp_type; // enumeration for application polymorphism typedef enum @@ -120,32 +120,32 @@ typedef enum AC_APPLY_WIND_SWING, AC_APPLY_WIND_FIX, AC_APPLY_MAX -} ac_apply; +} t_ac_apply; typedef struct _ac_hex { UINT8 len; UINT8 *data; -} ac_hex; +} t_ac_hex; typedef struct _ac_level { UINT16 low; UINT16 high; -} ac_level; +} t_ac_level; typedef struct _ac_bootcode { UINT16 len; UINT16 data[16]; -} ac_bootcode; +} t_ac_bootcode; typedef struct _ac_delaycode { INT16 pos; UINT16 time[8]; UINT16 time_cnt; -} ac_delaycode; +} t_ac_delaycode; /* * the array of tag_100X application data @@ -157,78 +157,78 @@ typedef struct _tag_comp_type_1 { UINT8 seg_len; UINT8 *segment; -} tag_comp; +} t_tag_comp; typedef struct _tag_swing_info { swing_type type; UINT8 mode_count; UINT8 dir_index; -} swing_info; +} t_swing_info; typedef struct _tag_power_1 { UINT8 len; - tag_comp comp_data[AC_POWER_MAX]; -} power_1; + t_tag_comp comp_data[AC_POWER_MAX]; +} t_power_1; typedef struct _tag_temp_1 { UINT8 len; UINT8 type; - tag_comp comp_data[AC_TEMP_MAX]; -} temp_1; + t_tag_comp comp_data[AC_TEMP_MAX]; +} t_temp_1; typedef struct tag_mode_1 { UINT8 len; - tag_comp comp_data[AC_MODE_MAX]; -} mode_1; + t_tag_comp comp_data[AC_MODE_MAX]; +} t_mode_1; typedef struct tag_speed_1 { UINT8 len; - tag_comp comp_data[AC_WS_MAX]; -} speed_1; + t_tag_comp comp_data[AC_WS_MAX]; +} t_speed_1; typedef struct tag_swing_1 { UINT8 len; UINT16 count; - tag_comp *comp_data; -} swing_1; + t_tag_comp *comp_data; +} t_swing_1; typedef struct tag_temp_2 { UINT8 len; UINT8 type; - tag_comp comp_data[AC_TEMP_MAX]; -} temp_2; + t_tag_comp comp_data[AC_TEMP_MAX]; +} t_temp_2; typedef struct tag_mode_2 { UINT8 len; - tag_comp comp_data[AC_MODE_MAX]; -} mode_2; + t_tag_comp comp_data[AC_MODE_MAX]; +} t_mode_2; typedef struct tag_speed_2 { UINT8 len; - tag_comp comp_data[AC_WS_MAX]; -} speed_2; + t_tag_comp comp_data[AC_WS_MAX]; +} t_speed_2; typedef struct tag_swing_2 { UINT8 len; UINT16 count; - tag_comp *comp_data; -} swing_2; + t_tag_comp *comp_data; +} t_swing_2; #if defined SUPPORT_HORIZONTAL_SWING typedef struct tag_horiswing_1 { UINT16 len; - tag_comp comp_data[AC_HORI_SWING_MAX]; + t_tag_comp comp_data[AC_HORI_SWING_MAX]; } hori_swing_1; #endif @@ -241,39 +241,39 @@ typedef struct _tag_checksum_data UINT8 checksum_byte_pos; UINT8 checksum_plus; UINT8 *spec_pos; -} tag_checksum_data; +} t_tag_checksum_data; typedef struct tag_checksum { UINT8 len; UINT16 count; - tag_checksum_data *checksum_data; -} tchecksum; + t_tag_checksum_data *checksum_data; +} t_checksum; typedef struct tag_function_1 { UINT8 len; - tag_comp comp_data[AC_FUNCTION_MAX - 1]; -} function_1; + t_tag_comp comp_data[AC_FUNCTION_MAX - 1]; +} t_function_1; typedef struct tag_function_2 { UINT8 len; - tag_comp comp_data[AC_FUNCTION_MAX - 1]; -} function_2; + t_tag_comp comp_data[AC_FUNCTION_MAX - 1]; +} t_function_2; typedef struct tag_solo_code { UINT8 len; UINT8 solo_func_count; UINT8 solo_function_codes[AC_FUNCTION_MAX - 1]; -} solo_code; +} t_solo_code; typedef struct _ac_bitnum { INT16 pos; UINT16 bits; -} ac_bitnum; +} t_ac_bit_num; typedef enum { @@ -283,7 +283,7 @@ typedef enum N_FAN, N_DRY, N_MODE_MAX, -} ac_n_mode; +} t_ac_n_mode; typedef enum { @@ -296,68 +296,69 @@ typedef enum CHECKSUM_TYPE_SPEC_HALF_BYTE_ONE_BYTE, CHECKSUM_TYPE_SPEC_HALF_BYTE_INVERSE_ONE_BYTE, CHECKSUM_TYPE_MAX, -} checksum_type; +} t_checksum_type; typedef struct _ac_n_mode_info { UINT8 enable; - UINT8 allspeed; - UINT8 alltemp; + UINT8 all_speed; + UINT8 all_temp; UINT8 temp[AC_TEMP_MAX]; UINT8 temp_cnt; UINT8 speed[AC_WS_MAX]; UINT8 speed_cnt; -} ac_n_mode_info; +} t_ac_n_mode_info; typedef struct ac_protocol { UINT8 endian; - // ac_hex default_code; - ac_hex default_code; - ac_level zero; - ac_level one; - ac_bootcode bootcode; - ac_delaycode dc[MAX_DELAYCODE_NUM]; - power_1 power1; - temp_1 temp1; - mode_1 mode1; - speed_1 speed1; - swing_1 swing1; - tchecksum checksum; + // t_ac_hex default_code; + t_ac_hex default_code; + t_ac_level zero; + t_ac_level one; + t_ac_bootcode boot_code; + t_ac_delaycode dc[MAX_DELAYCODE_NUM]; + t_power_1 power1; + t_temp_1 temp1; + t_mode_1 mode1; + t_speed_1 speed1; + t_swing_1 swing1; + t_checksum checksum; - function_1 function1; - function_2 function2; + t_function_1 function1; + t_function_2 function2; - temp_2 temp2; - mode_2 mode2; - speed_2 speed2; - swing_2 swing2; + t_temp_2 temp2; + t_mode_2 mode2; + t_speed_2 speed2; + t_swing_2 swing2; - swing_info si; - solo_code sc; + t_swing_info si; + t_solo_code sc; UINT8 swing_status; BOOL change_wind_direction; UINT16 dc_cnt; - ac_bitnum bitnum[MAX_BITNUM]; - UINT16 bitnum_cnt; + t_ac_bit_num bit_num[MAX_BITNUM]; + UINT16 bit_num_cnt; UINT16 repeat_times; - UINT16 frame_length; - ac_n_mode_info n_mode[N_MODE_MAX]; + t_ac_n_mode_info n_mode[N_MODE_MAX]; UINT16 code_cnt; - UINT8 lastbit; + UINT8 last_bit; UINT16 *time; UINT8 solo_function_mark; -} protocol; + + UINT16 frame_length; +} t_ac_protocol; typedef struct tag_head { UINT16 tag; UINT16 len; unsigned short offset; - UINT8 *pdata; + UINT8 *p_data; } t_tag_head; struct ir_bin_buffer @@ -369,19 +370,18 @@ struct ir_bin_buffer typedef struct REMOTE_AC_STATUS { - ac_power acPower; - ac_temperature acTemp; - ac_mode acMode; - ac_swing acWindDir; - ac_wind_speed acWindSpeed; - UINT8 acDisplay; - UINT8 acSleep; - UINT8 acTimer; -} remote_ac_status_t; + t_ac_power ac_power; + t_ac_temperature ac_temp; + t_ac_mode ac_mode; + t_ac_swing ac_wind_dir; + t_ac_wind_speed ac_wind_speed; + UINT8 ac_display; + UINT8 ac_sleep; + UINT8 ac_timer; +} t_remote_ac_status; // function polymorphism -typedef INT8 (*lp_apply_ac_parameter)(remote_ac_status_t ac_status, UINT8 function_code); - +typedef INT8 (*lp_apply_ac_parameter)(t_remote_ac_status ac_status, UINT8 function_code); #define TAG_AC_BOOT_CODE 1 #define TAG_AC_ZERO 2 @@ -389,7 +389,7 @@ typedef INT8 (*lp_apply_ac_parameter)(remote_ac_status_t ac_status, UINT8 functi #define TAG_AC_DELAY_CODE 4 #define TAG_AC_FRAME_LENGTH 5 #define TAG_AC_ENDIAN 6 -#define TAG_AC_LASTBIT 7 +#define TAG_AC_LAST_BIT 7 #define TAG_AC_POWER_1 21 #define TAG_AC_DEFAULT_CODE 22 @@ -413,17 +413,17 @@ typedef INT8 (*lp_apply_ac_parameter)(remote_ac_status_t ac_status, UINT8 functi #define TAG_AC_BAN_FUNCTION_IN_DRY_MODE 45 #define TAG_AC_SWING_INFO 46 #define TAG_AC_REPEAT_TIMES 47 -#define TAG_AC_BITNUM 48 +#define TAG_AC_BIT_NUM 48 // definition about size -#define PROTOCOL_SIZE (sizeof(protocol)) +#define PROTOCOL_SIZE (sizeof(t_ac_protocol)) /* exported variables */ extern UINT8 *ir_hex_code; extern UINT8 ir_hex_len; -extern protocol *context; +extern t_ac_protocol *context; extern INT8 ir_ac_lib_parse(); diff --git a/cc26xx-example/ti/BLE-CC264x/ble_cc26xx/Projects/ble/SimpleBLEPeripheral-IREXT/CC26xx/Source/Application/Irext/include/ir_ac_parse_forbidden_info.h b/cc26xx-example/ti/BLE-CC264x/ble_cc26xx/Projects/ble/SimpleBLEPeripheral-IREXT/CC26xx/Source/Application/Irext/include/ir_ac_parse_forbidden_info.h index c0cce82..8f0f5b1 100644 --- a/cc26xx-example/ti/BLE-CC264x/ble_cc26xx/Projects/ble/SimpleBLEPeripheral-IREXT/CC26xx/Source/Application/Irext/include/ir_ac_parse_forbidden_info.h +++ b/cc26xx-example/ti/BLE-CC264x/ble_cc26xx/Projects/ble/SimpleBLEPeripheral-IREXT/CC26xx/Source/Application/Irext/include/ir_ac_parse_forbidden_info.h @@ -19,7 +19,7 @@ extern "C" #include "ir_decode.h" -extern INT8 parse_nmode(struct tag_head *tag, ac_n_mode index); +extern INT8 parse_nmode(struct tag_head *tag, t_ac_n_mode index); #ifdef __cplusplus } diff --git a/cc26xx-example/ti/BLE-CC264x/ble_cc26xx/Projects/ble/SimpleBLEPeripheral-IREXT/CC26xx/Source/Application/Irext/include/ir_ac_parse_parameter.h b/cc26xx-example/ti/BLE-CC264x/ble_cc26xx/Projects/ble/SimpleBLEPeripheral-IREXT/CC26xx/Source/Application/Irext/include/ir_ac_parse_parameter.h index 1da7132..6d53e89 100644 --- a/cc26xx-example/ti/BLE-CC264x/ble_cc26xx/Projects/ble/SimpleBLEPeripheral-IREXT/CC26xx/Source/Application/Irext/include/ir_ac_parse_parameter.h +++ b/cc26xx-example/ti/BLE-CC264x/ble_cc26xx/Projects/ble/SimpleBLEPeripheral-IREXT/CC26xx/Source/Application/Irext/include/ir_ac_parse_parameter.h @@ -19,37 +19,37 @@ extern "C" #include "ir_decode.h" -extern INT8 parse_common_ac_parameter(t_tag_head *tag, tag_comp *comp_data, UINT8 with_end, UINT8 type); +extern INT8 parse_common_ac_parameter(t_tag_head *tag, t_tag_comp *comp_data, UINT8 with_end, UINT8 type); -extern INT8 parse_default_code(struct tag_head *tag, ac_hex *default_code); +extern INT8 parse_default_code(struct tag_head *tag, t_ac_hex *default_code); -extern INT8 parse_power_1(struct tag_head *tag, power_1 *power1); +extern INT8 parse_power_1(struct tag_head *tag, t_power_1 *power1); -extern INT8 parse_temp_1(struct tag_head *tag, temp_1 *temp1); +extern INT8 parse_temp_1(struct tag_head *tag, t_temp_1 *temp1); -extern INT8 parse_mode_1(struct tag_head *tag, mode_1 *mode1); +extern INT8 parse_mode_1(struct tag_head *tag, t_mode_1 *mode1); -extern INT8 parse_speed_1(struct tag_head *tag, speed_1 *speed1); +extern INT8 parse_speed_1(struct tag_head *tag, t_speed_1 *speed1); -extern INT8 parse_swing_1(struct tag_head *tag, swing_1 *swing1, UINT16 swing_count); +extern INT8 parse_swing_1(struct tag_head *tag, t_swing_1 *swing1, UINT16 swing_count); -extern INT8 parse_checksum(struct tag_head *tag, tchecksum *checksum); +extern INT8 parse_checksum(struct tag_head *tag, t_checksum *checksum); -extern INT8 parse_function_1_tag29(struct tag_head *tag, function_1 *function1); +extern INT8 parse_function_1_tag29(struct tag_head *tag, t_function_1 *function1); -extern INT8 parse_temp_2(struct tag_head *tag, temp_2 *temp2); +extern INT8 parse_temp_2(struct tag_head *tag, t_temp_2 *temp2); -extern INT8 parse_mode_2(struct tag_head *tag, mode_2 *mode2); +extern INT8 parse_mode_2(struct tag_head *tag, t_mode_2 *mode2); -extern INT8 parse_speed_2(struct tag_head *tag, speed_2 *speed2); +extern INT8 parse_speed_2(struct tag_head *tag, t_speed_2 *speed2); -extern INT8 parse_swing_2(struct tag_head *tag, swing_2 *swing2, UINT16 swing_count); +extern INT8 parse_swing_2(struct tag_head *tag, t_swing_2 *swing2, UINT16 swing_count); -extern INT8 parse_function_2_tag34(struct tag_head *tag, function_2 *function2); +extern INT8 parse_function_2_tag34(struct tag_head *tag, t_function_2 *function2); -extern INT8 parse_swing_info(struct tag_head *tag, swing_info *si); +extern INT8 parse_swing_info(struct tag_head *tag, t_swing_info *si); -extern INT8 parse_solo_code(struct tag_head *tag, solo_code *sc); +extern INT8 parse_solo_code(struct tag_head *tag, t_solo_code *sc); #ifdef __cplusplus } diff --git a/cc26xx-example/ti/BLE-CC264x/ble_cc26xx/Projects/ble/SimpleBLEPeripheral-IREXT/CC26xx/Source/Application/Irext/include/ir_decode.h b/cc26xx-example/ti/BLE-CC264x/ble_cc26xx/Projects/ble/SimpleBLEPeripheral-IREXT/CC26xx/Source/Application/Irext/include/ir_decode.h index 5ae4b17..b2fff07 100644 --- a/cc26xx-example/ti/BLE-CC264x/ble_cc26xx/Projects/ble/SimpleBLEPeripheral-IREXT/CC26xx/Source/Application/Irext/include/ir_decode.h +++ b/cc26xx-example/ti/BLE-CC264x/ble_cc26xx/Projects/ble/SimpleBLEPeripheral-IREXT/CC26xx/Source/Application/Irext/include/ir_decode.h @@ -75,7 +75,7 @@ extern INT8 ir_binary_open(const UINT8 category, const UINT8 sub_category, UINT8 * * returns: length of decoded data (0 indicates decode failure) */ -extern UINT16 ir_decode(UINT8 key_code, UINT16* user_data, remote_ac_status_t* ac_status, BOOL change_wind_direction); +extern UINT16 ir_decode(UINT8 key_code, UINT16* user_data, t_remote_ac_status* ac_status, BOOL change_wind_direction); /** * function ir_close diff --git a/cc26xx-example/ti/BLE-CC264x/ble_cc26xx/Projects/ble/SimpleBLEPeripheral-IREXT/CC26xx/Source/Application/Irext/include/ir_tv_control.h b/cc26xx-example/ti/BLE-CC264x/ble_cc26xx/Projects/ble/SimpleBLEPeripheral-IREXT/CC26xx/Source/Application/Irext/include/ir_tv_control.h index a4e1661..9e86741 100644 --- a/cc26xx-example/ti/BLE-CC264x/ble_cc26xx/Projects/ble/SimpleBLEPeripheral-IREXT/CC26xx/Source/Application/Irext/include/ir_tv_control.h +++ b/cc26xx-example/ti/BLE-CC264x/ble_cc26xx/Projects/ble/SimpleBLEPeripheral-IREXT/CC26xx/Source/Application/Irext/include/ir_tv_control.h @@ -63,7 +63,7 @@ typedef enum ir_flags IRDA_E, IRDA_F, IRDA_MAX = 20, -} ir_flags_t; +} t_ir_flags; typedef struct ir_data { @@ -71,7 +71,7 @@ typedef struct ir_data UINT8 lsb; UINT8 mode; UINT8 index; -} ir_data_t; +} t_ir_data; #if !defined BOARD_51 #pragma pack(1) @@ -81,7 +81,8 @@ typedef struct ir_cycles UINT8 flag; UINT16 mask; UINT16 space; -} ir_cycles_t; +} t_ir_cycles; + #if !defined BOARD_51 #pragma pack() #endif @@ -113,7 +114,7 @@ typedef enum tv_key_value TV_8, TV_9, TV_KEY_MAX, -} tv_key_value_t; +} t_tv_key_value; typedef enum stb_key_value @@ -143,7 +144,7 @@ typedef enum stb_key_value STB_8, STB_9, STB_KEY_MAX, -} stb_key_value_t; +} t_stb_key_value; typedef enum nw_key_value { @@ -169,7 +170,7 @@ typedef enum nw_key_value NW_8, NW_9, NW_KEY_MAX, -} nw_key_value_t; +} t_nw_key_value; typedef enum cm_key_value { @@ -189,13 +190,13 @@ typedef enum cm_key_value CM_MENU, CM_MODE, CM_KEY_MAX, -} cm_key_value_t; +} t_cm_key_value; typedef struct ir_data_tv { char magic[4]; UINT8 per_keycode_bytes; -} ir_data_tv_t; +} t_ir_data_tv; extern INT8 tv_lib_open(UINT8 *binary, UINT16 binary_length); diff --git a/cc26xx-example/ti/BLE-CC264x/ble_cc26xx/Projects/ble/SimpleBLEPeripheral-IREXT/CC26xx/Source/Application/Irext/include/ir_utils.h b/cc26xx-example/ti/BLE-CC264x/ble_cc26xx/Projects/ble/SimpleBLEPeripheral-IREXT/CC26xx/Source/Application/Irext/include/ir_utils.h index 2f036ae..667bdf1 100644 --- a/cc26xx-example/ti/BLE-CC264x/ble_cc26xx/Projects/ble/SimpleBLEPeripheral-IREXT/CC26xx/Source/Application/Irext/include/ir_utils.h +++ b/cc26xx-example/ti/BLE-CC264x/ble_cc26xx/Projects/ble/SimpleBLEPeripheral-IREXT/CC26xx/Source/Application/Irext/include/ir_utils.h @@ -22,13 +22,11 @@ extern "C" #include -extern void string_to_hex(UINT8 *p, ac_hex *pac_hex, UINT16 len); - -extern void string_to_intArray(UINT8 *p, UINT8 *binary_code, UINT16 len); +extern void string_to_hex(UINT8 *p, t_ac_hex *pac_hex); extern void string_to_hex_common(UINT8 *p, UINT8 *hex_data, UINT16 len); -extern BOOL isin(UINT8 array[], UINT8 value, UINT8 len); +extern BOOL is_in(const UINT8 *array, UINT8 value, UINT8 len); extern void hex_byte_to_double_char(char *dest, UINT8 length, UINT8 src); diff --git a/cc26xx-example/ti/BLE-CC264x/ble_cc26xx/Projects/ble/SimpleBLEPeripheral-IREXT/CC26xx/Source/Application/Irext/src/ir_ac_apply.c b/cc26xx-example/ti/BLE-CC264x/ble_cc26xx/Projects/ble/SimpleBLEPeripheral-IREXT/CC26xx/Source/Application/Irext/src/ir_ac_apply.c index 7206bcc..905ddc8 100644 --- a/cc26xx-example/ti/BLE-CC264x/ble_cc26xx/Projects/ble/SimpleBLEPeripheral-IREXT/CC26xx/Source/Application/Irext/src/ir_ac_apply.c +++ b/cc26xx-example/ti/BLE-CC264x/ble_cc26xx/Projects/ble/SimpleBLEPeripheral-IREXT/CC26xx/Source/Application/Irext/src/ir_ac_apply.c @@ -17,16 +17,16 @@ static INT8 apply_ac_power(struct ac_protocol *protocol, UINT8 power_status); static INT8 apply_ac_mode(struct ac_protocol *protocol, UINT8 mode_status); -static INT8 apply_ac_temperature(struct ac_protocol *protocol, UINT8 temperature); +static INT8 apply_ac_temperature(struct ac_protocol *protocol, UINT8 temp_diff); static INT8 apply_ac_wind_speed(struct ac_protocol *protocol, UINT8 wind_speed); -static INT8 apply_ac_swing(struct ac_protocol *protocol, UINT8 swing_status); +static INT8 apply_ac_swing(struct ac_protocol *protocol, UINT8 swing_mode); static UINT8 has_function(struct ac_protocol *protocol, UINT8 function); -INT8 apply_ac_parameter_type_1(UINT8 *dc_data, tag_comp *comp_data, UINT8 current_seg, UINT8 is_temp) +INT8 apply_ac_parameter_type_1(UINT8 *dc_data, t_tag_comp *comp_data, UINT8 current_seg, UINT8 is_temp) { if (0 != (comp_data->seg_len & 0x01)) { @@ -45,7 +45,7 @@ INT8 apply_ac_parameter_type_1(UINT8 *dc_data, tag_comp *comp_data, UINT8 curren return IR_DECODE_SUCCEEDED; } -INT8 apply_ac_parameter_type_2(UINT8 *dc_data, tag_comp *comp_data, UINT8 current_seg, UINT8 is_temp) +INT8 apply_ac_parameter_type_2(UINT8 *dc_data, t_tag_comp *comp_data, UINT8 current_seg, UINT8 is_temp) { UINT8 start_bit = 0; UINT8 end_bit = 0; @@ -59,11 +59,10 @@ INT8 apply_ac_parameter_type_2(UINT8 *dc_data, tag_comp *comp_data, UINT8 curren return IR_DECODE_FAILED; } - // TODO: to be validated start_bit = comp_data->segment[current_seg]; end_bit = comp_data->segment[current_seg + 1]; cover_byte_pos_hi = start_bit >> 3; - cover_byte_pos_lo = (end_bit - 1) >> 3; + cover_byte_pos_lo = (UINT8) (end_bit - 1) >> 3; if (cover_byte_pos_hi == cover_byte_pos_lo) { // cover_byte_pos_hi or cover_bytes_pos_lo is target byte to be applied with AC parameter @@ -72,12 +71,12 @@ INT8 apply_ac_parameter_type_2(UINT8 *dc_data, tag_comp *comp_data, UINT8 curren UINT8 int_start_bit = start_bit - (cover_byte_pos_hi << 3); UINT8 int_end_bit = end_bit - (cover_byte_pos_lo << 3); UINT8 bit_range = end_bit - start_bit; - UINT8 mask = (0xFF << (8 - int_start_bit)) | (0xFF >> int_end_bit); + UINT8 mask = (UINT8) ((0xFF << (8 - int_start_bit)) | (0xFF >> int_end_bit)); UINT8 origin = dc_data[cover_byte_pos_lo]; if (TRUE == is_temp) { - move_bit = 8 - int_end_bit; + move_bit = (UINT8) (8 - int_end_bit); value = (origin & mask) | (((((origin & ~mask) >> move_bit) + raw_value) << move_bit) & ~mask); } else @@ -88,14 +87,13 @@ INT8 apply_ac_parameter_type_2(UINT8 *dc_data, tag_comp *comp_data, UINT8 curren } else { - UINT8 value = 0x00; - UINT8 origin_hi = 0x00; - UINT8 origin_lo = 0x00; - UINT8 mask_hi = 0x00; - UINT8 mask_lo = 0x00; - UINT8 raw_value = 0x00; - UINT8 int_start_bit = 0x00; - UINT8 int_end_bit = 0x00; + UINT8 origin_hi = 0; + UINT8 origin_lo = 0; + UINT8 mask_hi = 0; + UINT8 mask_lo = 0; + UINT8 raw_value = 0; + UINT8 int_start_bit = 0; + UINT8 int_end_bit = 0; if (cover_byte_pos_hi > cover_byte_pos_lo) { @@ -111,8 +109,8 @@ INT8 apply_ac_parameter_type_2(UINT8 *dc_data, tag_comp *comp_data, UINT8 curren int_start_bit = start_bit - (cover_byte_pos_hi << 3); int_end_bit = end_bit - (cover_byte_pos_lo << 3); - mask_hi = 0xFF << (8 - int_start_bit); - mask_lo = 0xFF >> int_end_bit; + mask_hi = (UINT8) 0xFF << (8 - int_start_bit); + mask_lo = (UINT8) 0xFF >> int_end_bit; value = ((origin_hi & ~mask_hi) << int_end_bit) | ((origin_lo & ~mask_lo) >> (8 - int_end_bit)); @@ -121,11 +119,11 @@ INT8 apply_ac_parameter_type_2(UINT8 *dc_data, tag_comp *comp_data, UINT8 curren raw_value += value; } - dc_data[cover_byte_pos_hi] = (origin_hi & mask_hi) | - (((0xFF >> (8 - bit_range)) & raw_value) >> int_end_bit); + dc_data[cover_byte_pos_hi] = (UINT8) ((origin_hi & mask_hi) | + (((0xFF >> (8 - bit_range)) & raw_value) >> int_end_bit)); - dc_data[cover_byte_pos_lo] = (origin_lo & mask_lo) | - (((0xFF >> (8 - bit_range)) & raw_value) << (8 - int_end_bit)); + dc_data[cover_byte_pos_lo] = (UINT8) ((origin_lo & mask_lo) | + (((0xFF >> (8 - bit_range)) & raw_value) << (8 - int_end_bit))); } return IR_DECODE_SUCCEEDED; @@ -346,7 +344,7 @@ static INT8 apply_ac_swing(struct ac_protocol *protocol, UINT8 swing_mode) return IR_DECODE_SUCCEEDED; } -static INT8 apply_checksum_byte(UINT8 *ac_code, tag_checksum_data cs, BOOL inverse) +static INT8 apply_checksum_byte(UINT8 *ac_code, t_tag_checksum_data cs, BOOL inverse) { UINT16 i = 0; UINT8 checksum = 0x00; @@ -374,7 +372,7 @@ static INT8 apply_checksum_byte(UINT8 *ac_code, tag_checksum_data cs, BOOL inver return IR_DECODE_SUCCEEDED; } -static INT8 apply_checksum_halfbyte(UINT8 *ac_code, tag_checksum_data cs, BOOL inverse) +static INT8 apply_checksum_halfbyte(UINT8 *ac_code, t_tag_checksum_data cs, BOOL inverse) { UINT16 i = 0; UINT8 checksum = 0x00; @@ -402,7 +400,7 @@ static INT8 apply_checksum_halfbyte(UINT8 *ac_code, tag_checksum_data cs, BOOL i return IR_DECODE_SUCCEEDED; } -static INT8 apply_checksum_spec_byte(UINT8 *ac_code, tag_checksum_data cs, BOOL inverse) +static INT8 apply_checksum_spec_byte(UINT8 *ac_code, t_tag_checksum_data cs, BOOL inverse) { UINT16 i = 0; UINT8 apply_byte_pos = 0; @@ -442,18 +440,18 @@ static INT8 apply_checksum_spec_byte(UINT8 *ac_code, tag_checksum_data cs, BOOL if (0 == (cs.checksum_byte_pos & 0x01)) { // save low bits and add checksum as high bits - ac_code[apply_byte_pos] = (ac_code[apply_byte_pos] & 0x0F) | (checksum << 4); + ac_code[apply_byte_pos] = (UINT8) ((ac_code[apply_byte_pos] & 0x0F) | (checksum << 4)); } else { // save high bits and add checksum as low bits - ac_code[apply_byte_pos] = (ac_code[apply_byte_pos] & 0xF0) | (checksum & 0x0F); + ac_code[apply_byte_pos] = (UINT8) ((ac_code[apply_byte_pos] & 0xF0) | (checksum & 0x0F)); } return IR_DECODE_SUCCEEDED; } -static INT8 apply_checksum_spec_byte_onebyte(UINT8 *ac_code, tag_checksum_data cs, BOOL inverse) +static INT8 apply_checksum_spec_byte_onebyte(UINT8 *ac_code, t_tag_checksum_data cs, BOOL inverse) { UINT16 i = 0; UINT8 apply_byte_pos = 0; @@ -605,15 +603,15 @@ INT8 apply_checksum(struct ac_protocol *protocol) return IR_DECODE_SUCCEEDED; } -INT8 apply_power(remote_ac_status_t ac_status, UINT8 function_code) +INT8 apply_power(t_remote_ac_status ac_status, UINT8 function_code) { - apply_ac_power(context, ac_status.acPower); + apply_ac_power(context, ac_status.ac_power); return IR_DECODE_SUCCEEDED; } -INT8 apply_mode(remote_ac_status_t ac_status, UINT8 function_code) +INT8 apply_mode(t_remote_ac_status ac_status, UINT8 function_code) { - if (IR_DECODE_FAILED == apply_ac_mode(context, ac_status.acMode)) + if (IR_DECODE_FAILED == apply_ac_mode(context, ac_status.ac_mode)) { // do not implement this mechanism since mode, temperature, wind // speed would have unspecified function @@ -626,16 +624,16 @@ INT8 apply_mode(remote_ac_status_t ac_status, UINT8 function_code) return IR_DECODE_SUCCEEDED; } -INT8 apply_wind_speed(remote_ac_status_t ac_status, UINT8 function_code) +INT8 apply_wind_speed(t_remote_ac_status ac_status, UINT8 function_code) { - if (FALSE == context->n_mode[ac_status.acMode].allspeed) + if (FALSE == context->n_mode[ac_status.ac_mode].all_speed) { // if this level is not in black list - if (!isin(context->n_mode[ac_status.acMode].speed, - ac_status.acWindSpeed, - context->n_mode[ac_status.acMode].speed_cnt)) + if (!is_in(context->n_mode[ac_status.ac_mode].speed, + ac_status.ac_wind_speed, + context->n_mode[ac_status.ac_mode].speed_cnt)) { - if (IR_DECODE_FAILED == apply_ac_wind_speed(context, ac_status.acWindSpeed) && + if (IR_DECODE_FAILED == apply_ac_wind_speed(context, ac_status.ac_wind_speed) && function_code == AC_FUNCTION_WIND_SPEED) { // do not implement this mechanism since mode, temperature, wind @@ -676,7 +674,7 @@ INT8 apply_wind_speed(remote_ac_status_t ac_status, UINT8 function_code) return IR_DECODE_SUCCEEDED; } -INT8 apply_swing(remote_ac_status_t ac_status, UINT8 function_code) +INT8 apply_swing(t_remote_ac_status ac_status, UINT8 function_code) { if (function_code == AC_FUNCTION_WIND_FIX) { @@ -719,15 +717,15 @@ INT8 apply_swing(remote_ac_status_t ac_status, UINT8 function_code) return IR_DECODE_SUCCEEDED; } -INT8 apply_temperature(remote_ac_status_t ac_status, UINT8 function_code) +INT8 apply_temperature(t_remote_ac_status ac_status, UINT8 function_code) { - if (FALSE == context->n_mode[ac_status.acMode].alltemp) + if (FALSE == context->n_mode[ac_status.ac_mode].all_temp) { - if (!isin(context->n_mode[ac_status.acMode].temp, - ac_status.acTemp, - context->n_mode[ac_status.acMode].temp_cnt)) + if (!is_in(context->n_mode[ac_status.ac_mode].temp, + ac_status.ac_temp, + context->n_mode[ac_status.ac_mode].temp_cnt)) { - if (IR_DECODE_FAILED == apply_ac_temperature(context, ac_status.acTemp)) + if (IR_DECODE_FAILED == apply_ac_temperature(context, ac_status.ac_temp)) { if (function_code == AC_FUNCTION_TEMPERATURE_UP /*&& FALSE == has_function(context, AC_FUNCTION_TEMPERATURE_UP)*/) diff --git a/cc26xx-example/ti/BLE-CC264x/ble_cc26xx/Projects/ble/SimpleBLEPeripheral-IREXT/CC26xx/Source/Application/Irext/src/ir_ac_binary_parse.c b/cc26xx-example/ti/BLE-CC264x/ble_cc26xx/Projects/ble/SimpleBLEPeripheral-IREXT/CC26xx/Source/Application/Irext/src/ir_ac_binary_parse.c index cf07677..747a8b8 100644 --- a/cc26xx-example/ti/BLE-CC264x/ble_cc26xx/Projects/ble/SimpleBLEPeripheral-IREXT/CC26xx/Source/Application/Irext/src/ir_ac_binary_parse.c +++ b/cc26xx-example/ti/BLE-CC264x/ble_cc26xx/Projects/ble/SimpleBLEPeripheral-IREXT/CC26xx/Source/Application/Irext/src/ir_ac_binary_parse.c @@ -114,7 +114,7 @@ INT8 binary_parse_data() UINT16 i = 0; for (i = 0; i < tag_count; i++) { - tags[i].pdata = p_ir_buffer->data + tags[i].offset + tag_head_offset; + tags[i].p_data = p_ir_buffer->data + tags[i].offset + tag_head_offset; } return IR_DECODE_SUCCEEDED; diff --git a/cc26xx-example/ti/BLE-CC264x/ble_cc26xx/Projects/ble/SimpleBLEPeripheral-IREXT/CC26xx/Source/Application/Irext/src/ir_ac_build_frame.c b/cc26xx-example/ti/BLE-CC264x/ble_cc26xx/Projects/ble/SimpleBLEPeripheral-IREXT/CC26xx/Source/Application/Irext/src/ir_ac_build_frame.c index 1cf2b75..f3f767d 100644 --- a/cc26xx-example/ti/BLE-CC264x/ble_cc26xx/Projects/ble/SimpleBLEPeripheral-IREXT/CC26xx/Source/Application/Irext/src/ir_ac_build_frame.c +++ b/cc26xx-example/ti/BLE-CC264x/ble_cc26xx/Projects/ble/SimpleBLEPeripheral-IREXT/CC26xx/Source/Application/Irext/src/ir_ac_build_frame.c @@ -12,7 +12,7 @@ Revision log: #include "../include/ir_ac_build_frame.h" #include "../include/ir_decode.h" -extern protocol *context; +extern t_ac_protocol *context; //return bit number per byte,default value is 8 @@ -21,19 +21,19 @@ UINT8 bits_per_byte(UINT8 index) UINT8 i = 0; UINT8 size = 0; - if (context->bitnum_cnt == 0) + if (context->bit_num_cnt == 0) return 8; //defaut value - if (context->bitnum_cnt >= MAX_BITNUM) + if (context->bit_num_cnt >= MAX_BITNUM) size = MAX_BITNUM; else - size = (UINT8) context->bitnum_cnt; + size = (UINT8) context->bit_num_cnt; for (i = 0; i < size; i++) { - if (context->bitnum[i].pos == index) - return (UINT8) context->bitnum[i].bits; - if (context->bitnum[i].pos > index) + if (context->bit_num[i].pos == index) + return (UINT8) context->bit_num[i].bits; + if (context->bit_num[i].pos > index) return 8; } return 8; @@ -67,7 +67,7 @@ UINT16 add_delaycode(UINT8 index) } } - if ((context->lastbit == 0) && (index == (ir_hex_len - 1))) + if ((context->last_bit == 0) && (index == (ir_hex_len - 1))) { context->time[context->code_cnt++] = context->one.low; //high } @@ -97,11 +97,11 @@ UINT16 create_ir_frame() context->code_cnt = 0; // boot code - for (i = 0; i < context->bootcode.len; i++) + for (i = 0; i < context->boot_code.len; i++) { - context->time[context->code_cnt++] = context->bootcode.data[i]; + context->time[context->code_cnt++] = context->boot_code.data[i]; } - //code_cnt += context->bootcode.len; + //code_cnt += context->boot_code.len; for (i = 0; i < ir_hex_len; i++) { diff --git a/cc26xx-example/ti/BLE-CC264x/ble_cc26xx/Projects/ble/SimpleBLEPeripheral-IREXT/CC26xx/Source/Application/Irext/src/ir_ac_control.c b/cc26xx-example/ti/BLE-CC264x/ble_cc26xx/Projects/ble/SimpleBLEPeripheral-IREXT/CC26xx/Source/Application/Irext/src/ir_ac_control.c index b84d882..2bd8219 100644 --- a/cc26xx-example/ti/BLE-CC264x/ble_cc26xx/Projects/ble/SimpleBLEPeripheral-IREXT/CC26xx/Source/Application/Irext/src/ir_ac_control.c +++ b/cc26xx-example/ti/BLE-CC264x/ble_cc26xx/Projects/ble/SimpleBLEPeripheral-IREXT/CC26xx/Source/Application/Irext/src/ir_ac_control.c @@ -30,7 +30,7 @@ static INT8 ir_context_init(); static INT8 ir_context_init() { - ir_memset(context, 0, sizeof(protocol)); + ir_memset(context, 0, sizeof(t_ac_protocol)); return IR_DECODE_SUCCEEDED; } @@ -59,14 +59,14 @@ INT8 ir_ac_lib_parse() binary_tags_info(); context->endian = 0; - context->lastbit = 0; + context->last_bit = 0; context->repeat_times = 1; for (i = 0; i < N_MODE_MAX; i++) { context->n_mode[i].enable = TRUE; - context->n_mode[i].allspeed = FALSE; - context->n_mode[i].alltemp = FALSE; + context->n_mode[i].all_speed = FALSE; + context->n_mode[i].all_temp = FALSE; ir_memset(context->n_mode[i].speed, 0x00, AC_WS_MAX); context->n_mode[i].speed_cnt = 0; ir_memset(context->n_mode[i].temp, 0x00, AC_TEMP_MAX); @@ -105,8 +105,8 @@ INT8 ir_ac_lib_parse() { context->swing1.count = context->si.mode_count; context->swing1.len = (UINT8) tags[i].len >> 1; - swing_space_size = sizeof(tag_comp) * context->si.mode_count; - context->swing1.comp_data = (tag_comp *) ir_malloc(swing_space_size); + swing_space_size = sizeof(t_tag_comp) * context->si.mode_count; + context->swing1.comp_data = (t_tag_comp *) ir_malloc(swing_space_size); if (NULL == context->swing1.comp_data) { return IR_DECODE_FAILED; @@ -125,8 +125,8 @@ INT8 ir_ac_lib_parse() { context->swing2.count = context->si.mode_count; context->swing2.len = (UINT8) tags[i].len >> 1; - swing_space_size = sizeof(tag_comp) * context->si.mode_count; - context->swing2.comp_data = (tag_comp *) ir_malloc(swing_space_size); + swing_space_size = sizeof(t_tag_comp) * context->si.mode_count; + context->swing2.comp_data = (t_tag_comp *) ir_malloc(swing_space_size); if (NULL == context->swing2.comp_data) { return IR_DECODE_FAILED; @@ -286,7 +286,7 @@ INT8 ir_ac_lib_parse() return IR_DECODE_FAILED; } } - else if (tags[i].tag == TAG_AC_BITNUM) + else if (tags[i].tag == TAG_AC_BIT_NUM) { if (IR_DECODE_FAILED == parse_bit_num(&tags[i])) { @@ -350,7 +350,7 @@ INT8 ir_ac_lib_parse() return IR_DECODE_FAILED; } } - if (tags[i].tag == TAG_AC_LASTBIT) + if (tags[i].tag == TAG_AC_LAST_BIT) { if (IR_DECODE_FAILED == parse_lastbit(&tags[i])) { @@ -382,7 +382,7 @@ INT8 ir_ac_lib_parse() // bit order from right to left : power, mode, temp+, temp-, wind_speed, swing, fix for (i = AC_FUNCTION_POWER; i < AC_FUNCTION_MAX; i++) { - if (isin(context->sc.solo_function_codes, i, context->sc.solo_func_count)) + if (is_in(context->sc.solo_function_codes, i, context->sc.solo_func_count)) { context->solo_function_mark |= (1 << (i - 1)); } diff --git a/cc26xx-example/ti/BLE-CC264x/ble_cc26xx/Projects/ble/SimpleBLEPeripheral-IREXT/CC26xx/Source/Application/Irext/src/ir_ac_parse_forbidden_info.c b/cc26xx-example/ti/BLE-CC264x/ble_cc26xx/Projects/ble/SimpleBLEPeripheral-IREXT/CC26xx/Source/Application/Irext/src/ir_ac_parse_forbidden_info.c index d7c8c3a..0ea1c47 100644 --- a/cc26xx-example/ti/BLE-CC264x/ble_cc26xx/Projects/ble/SimpleBLEPeripheral-IREXT/CC26xx/Source/Application/Irext/src/ir_ac_parse_forbidden_info.c +++ b/cc26xx-example/ti/BLE-CC264x/ble_cc26xx/Projects/ble/SimpleBLEPeripheral-IREXT/CC26xx/Source/Application/Irext/src/ir_ac_parse_forbidden_info.c @@ -17,10 +17,10 @@ Revision log: #include "../include/ir_ac_parse_forbidden_info.h" -extern protocol *context; +extern t_ac_protocol *context; -INT8 parse_nmode_data_speed(char *pdata, ac_n_mode seq) +INT8 parse_nmode_data_speed(char *pdata, t_ac_n_mode seq) { char buf[16] = {0}; char *p = pdata; @@ -44,7 +44,7 @@ INT8 parse_nmode_data_speed(char *pdata, ac_n_mode seq) return IR_DECODE_SUCCEEDED; } -INT8 parse_nmode_data_temp(char *pdata, ac_n_mode seq) +INT8 parse_nmode_data_temp(char *pdata, t_ac_n_mode seq) { char buf[16] = {0}; @@ -68,7 +68,7 @@ INT8 parse_nmode_data_temp(char *pdata, ac_n_mode seq) return IR_DECODE_SUCCEEDED; } -INT8 parse_nmode_pos(char *buf, ac_n_mode index) +INT8 parse_nmode_pos(char *buf, t_ac_n_mode index) { UINT16 i = 0; char data[64] = {0}; @@ -77,11 +77,11 @@ INT8 parse_nmode_pos(char *buf, ac_n_mode index) { if (buf[0] == 'S' || buf[0] == 's') { - context->n_mode[index].allspeed = 1; + context->n_mode[index].all_speed = 1; } else if (buf[0] == 'T' || buf[0] == 't') { - context->n_mode[index].alltemp = 1; + context->n_mode[index].all_temp = 1; } return IR_DECODE_SUCCEEDED; } @@ -106,14 +106,14 @@ INT8 parse_nmode_pos(char *buf, ac_n_mode index) return IR_DECODE_SUCCEEDED; } -INT8 parse_nmode(struct tag_head *tag, ac_n_mode index) +INT8 parse_nmode(struct tag_head *tag, t_ac_n_mode index) { UINT16 i = 0; UINT16 preindex = 0; char buf[64] = {0}; - if (tag->pdata[0] == 'N' && tag->pdata[1] == 'A') + if (tag->p_data[0] == 'N' && tag->p_data[1] == 'A') { // ban this function directly context->n_mode[index].enable = 0; @@ -127,16 +127,16 @@ INT8 parse_nmode(struct tag_head *tag, ac_n_mode index) preindex = 0; for (i = 0; i < tag->len; i++) { - if (tag->pdata[i] == '|') + if (tag->p_data[i] == '|') { - ir_memcpy(buf, tag->pdata + preindex, i - preindex); + ir_memcpy(buf, tag->p_data + preindex, i - preindex); preindex = (UINT16) (i + 1); parse_nmode_pos(buf, index); ir_memset(buf, 0, 64); } } - ir_memcpy(buf, tag->pdata + preindex, i - preindex); + ir_memcpy(buf, tag->p_data + preindex, i - preindex); parse_nmode_pos(buf, index); ir_memset(buf, 0, 64); return IR_DECODE_SUCCEEDED; diff --git a/cc26xx-example/ti/BLE-CC264x/ble_cc26xx/Projects/ble/SimpleBLEPeripheral-IREXT/CC26xx/Source/Application/Irext/src/ir_ac_parse_frame_info.c b/cc26xx-example/ti/BLE-CC264x/ble_cc26xx/Projects/ble/SimpleBLEPeripheral-IREXT/CC26xx/Source/Application/Irext/src/ir_ac_parse_frame_info.c index 5a20932..b96bca1 100644 --- a/cc26xx-example/ti/BLE-CC264x/ble_cc26xx/Projects/ble/SimpleBLEPeripheral-IREXT/CC26xx/Source/Application/Irext/src/ir_ac_parse_frame_info.c +++ b/cc26xx-example/ti/BLE-CC264x/ble_cc26xx/Projects/ble/SimpleBLEPeripheral-IREXT/CC26xx/Source/Application/Irext/src/ir_ac_parse_frame_info.c @@ -28,7 +28,7 @@ INT8 parse_boot_code(struct tag_head *tag) { return IR_DECODE_FAILED; } - p = tag->pdata; + p = tag->p_data; if (NULL == p) { @@ -41,13 +41,13 @@ INT8 parse_boot_code(struct tag_head *tag) { index++; } - ir_memcpy(buf, tag->pdata + pos, index - pos); + ir_memcpy(buf, tag->p_data + pos, index - pos); pos = (UINT16) (index + 1); index = pos; - context->bootcode.data[cnt++] = (UINT16) (atoi((char *) buf)); + context->boot_code.data[cnt++] = (UINT16) (atoi((char *) buf)); ir_memset(buf, 0, 16); } - context->bootcode.len = cnt; + context->boot_code.len = cnt; return IR_DECODE_SUCCEEDED; } @@ -62,7 +62,7 @@ INT8 parse_zero(struct tag_head *tag) { return IR_DECODE_FAILED; } - p = tag->pdata; + p = tag->p_data; if (NULL == p) { @@ -74,8 +74,8 @@ INT8 parse_zero(struct tag_head *tag) index++; } - ir_memcpy(low, tag->pdata, index); - ir_memcpy(high, tag->pdata + index + 1, (size_t) (tag->len - index - 1)); + ir_memcpy(low, tag->p_data, index); + ir_memcpy(high, tag->p_data + index + 1, (size_t) (tag->len - index - 1)); context->zero.low = (UINT16) (atoi((char *) low)); context->zero.high = (UINT16) (atoi((char *) high)); @@ -93,7 +93,7 @@ INT8 parse_one(struct tag_head *tag) { return IR_DECODE_FAILED; } - p = tag->pdata; + p = tag->p_data; if (NULL == p) { @@ -104,8 +104,8 @@ INT8 parse_one(struct tag_head *tag) { index++; } - ir_memcpy(low, tag->pdata, index); - ir_memcpy(high, tag->pdata + index + 1, (size_t) (tag->len - index - 1)); + ir_memcpy(low, tag->p_data, index); + ir_memcpy(high, tag->p_data + index + 1, (size_t) (tag->len - index - 1)); context->one.low = (UINT16) (atoi((char *) low)); context->one.high = (UINT16) (atoi((char *) high)); @@ -183,16 +183,16 @@ INT8 parse_delay_code(struct tag_head *tag) for (i = 0; i < tag->len; i++) { - if (tag->pdata[i] == '|') + if (tag->p_data[i] == '|') { - ir_memcpy(buf, tag->pdata + preindex, i - preindex); + ir_memcpy(buf, tag->p_data + preindex, i - preindex); preindex = (UINT16) (i + 1); parse_delay_code_pos(buf); ir_memset(buf, 0, 64); } } - ir_memcpy(buf, tag->pdata + preindex, i - preindex); + ir_memcpy(buf, tag->p_data + preindex, i - preindex); parse_delay_code_pos(buf); ir_memset(buf, 0, 64); @@ -217,7 +217,7 @@ INT8 parse_frame_len(struct tag_head *tag, UINT16 len) ir_memset(temp, 0x00, len + 1); - ir_memcpy(temp, tag->pdata, len); + ir_memcpy(temp, tag->p_data, len); temp[len] = '\0'; context->frame_length = (UINT16) (atoi((char *) temp)); @@ -234,7 +234,7 @@ INT8 parse_endian(struct tag_head *tag) { return IR_DECODE_FAILED; } - ir_memcpy(buf, tag->pdata, tag->len); + ir_memcpy(buf, tag->p_data, tag->len); context->endian = (UINT8) (atoi((char *) buf)); return IR_DECODE_SUCCEEDED; } @@ -247,8 +247,8 @@ INT8 parse_lastbit(struct tag_head *tag) { return IR_DECODE_FAILED; } - ir_memcpy(buf, tag->pdata, tag->len); - context->lastbit = (UINT8) (atoi((char *) buf)); + ir_memcpy(buf, tag->p_data, tag->len); + context->last_bit = (UINT8) (atoi((char *) buf)); return IR_DECODE_SUCCEEDED; } @@ -260,7 +260,7 @@ INT8 parse_repeat_times(struct tag_head *tag) return IR_DECODE_FAILED; } - ir_memcpy(asc_code, tag->pdata, tag->len); + ir_memcpy(asc_code, tag->p_data, tag->len); context->repeat_times = (UINT16) (atoi((char *) asc_code)); @@ -287,9 +287,9 @@ INT8 parse_delay_code_tag48_pos(UINT8 *buf) } } - context->bitnum[context->bitnum_cnt].pos = (UINT16) (atoi((char *) start)); - context->bitnum[context->bitnum_cnt].bits = (UINT16) (atoi((char *) data)); - context->bitnum_cnt++; + context->bit_num[context->bit_num_cnt].pos = (UINT16) (atoi((char *) start)); + context->bit_num[context->bit_num_cnt].bits = (UINT16) (atoi((char *) data)); + context->bit_num_cnt++; return IR_DECODE_SUCCEEDED; } @@ -307,23 +307,23 @@ INT8 parse_bit_num(struct tag_head *tag) preindex = 0; for (i = 0; i < tag->len; i++) { - if (tag->pdata[i] == '|') + if (tag->p_data[i] == '|') { - ir_memcpy(buf, tag->pdata + preindex, i - preindex); + ir_memcpy(buf, tag->p_data + preindex, i - preindex); preindex = (UINT16) (i + 1); parse_delay_code_tag48_pos(buf); ir_memset(buf, 0, 64); } } - ir_memcpy(buf, tag->pdata + preindex, i - preindex); + ir_memcpy(buf, tag->p_data + preindex, i - preindex); parse_delay_code_tag48_pos(buf); ir_memset(buf, 0, 64); - for (i = 0; i < context->bitnum_cnt; i++) + for (i = 0; i < context->bit_num_cnt; i++) { - if (context->bitnum[i].pos == -1) - context->bitnum[i].pos = (UINT16) (context->default_code.len - 1); //convert -1 to last data pos + if (context->bit_num[i].pos == -1) + context->bit_num[i].pos = (UINT16) (context->default_code.len - 1); //convert -1 to last data pos } return IR_DECODE_SUCCEEDED; } diff --git a/cc26xx-example/ti/BLE-CC264x/ble_cc26xx/Projects/ble/SimpleBLEPeripheral-IREXT/CC26xx/Source/Application/Irext/src/ir_ac_parse_parameter.c b/cc26xx-example/ti/BLE-CC264x/ble_cc26xx/Projects/ble/SimpleBLEPeripheral-IREXT/CC26xx/Source/Application/Irext/src/ir_ac_parse_parameter.c index 39b03b7..70137bd 100644 --- a/cc26xx-example/ti/BLE-CC264x/ble_cc26xx/Projects/ble/SimpleBLEPeripheral-IREXT/CC26xx/Source/Application/Irext/src/ir_ac_parse_parameter.c +++ b/cc26xx-example/ti/BLE-CC264x/ble_cc26xx/Projects/ble/SimpleBLEPeripheral-IREXT/CC26xx/Source/Application/Irext/src/ir_ac_parse_parameter.c @@ -17,7 +17,7 @@ Revision log: #include "../include/ir_ac_parse_parameter.h" -INT8 parse_comp_data_type_1(UINT8 *data, UINT16 *trav_offset, tag_comp *comp) +INT8 parse_comp_data_type_1(UINT8 *data, UINT16 *trav_offset, t_tag_comp *comp) { UINT8 seg_len = data[*trav_offset]; (*trav_offset)++; @@ -43,7 +43,7 @@ INT8 parse_comp_data_type_1(UINT8 *data, UINT16 *trav_offset, tag_comp *comp) return IR_DECODE_SUCCEEDED; } -INT8 parse_comp_data_type_2(UINT8 *data, UINT16 *trav_offset, tag_comp *comp) +INT8 parse_comp_data_type_2(UINT8 *data, UINT16 *trav_offset, t_tag_comp *comp) { UINT8 seg_len = data[*trav_offset]; (*trav_offset)++; @@ -69,7 +69,7 @@ INT8 parse_comp_data_type_2(UINT8 *data, UINT16 *trav_offset, tag_comp *comp) return IR_DECODE_SUCCEEDED; } -INT8 parse_common_ac_parameter(t_tag_head *tag, tag_comp *comp_data, UINT8 with_end, UINT8 type) +INT8 parse_common_ac_parameter(t_tag_head *tag, t_tag_comp *comp_data, UINT8 with_end, UINT8 type) { UINT16 hex_len = 0; UINT16 trav_offset = 0; @@ -93,7 +93,7 @@ INT8 parse_common_ac_parameter(t_tag_head *tag, tag_comp *comp_data, UINT8 with_ return IR_DECODE_FAILED; } - string_to_hex_common(tag->pdata, hex_data, hex_len); + string_to_hex_common(tag->p_data, hex_data, hex_len); // parse hex data to AC data structure //*comp_len = hex_len; @@ -136,7 +136,7 @@ INT8 parse_common_ac_parameter(t_tag_head *tag, tag_comp *comp_data, UINT8 with_ return IR_DECODE_SUCCEEDED; } -INT8 parse_default_code(struct tag_head *tag, ac_hex *default_code) +INT8 parse_default_code(struct tag_head *tag, t_ac_hex *default_code) { UINT16 byteLen = 0; @@ -146,12 +146,12 @@ INT8 parse_default_code(struct tag_head *tag, ac_hex *default_code) } byteLen = tag->len >> 1; - string_to_hex(tag->pdata, default_code, byteLen); + string_to_hex(tag->p_data, default_code); return IR_DECODE_SUCCEEDED; } -INT8 parse_power_1(struct tag_head *tag, power_1 *power1) +INT8 parse_power_1(struct tag_head *tag, t_power_1 *power1) { UINT16 hex_len = 0; UINT16 trav_offset = 0; @@ -176,7 +176,7 @@ INT8 parse_power_1(struct tag_head *tag, power_1 *power1) return IR_DECODE_FAILED; } - string_to_hex_common(tag->pdata, hex_data, hex_len); + string_to_hex_common(tag->p_data, hex_data, hex_len); // parse hex data to power1 data structure power1->len = (UINT8) hex_len; @@ -201,7 +201,7 @@ INT8 parse_power_1(struct tag_head *tag, power_1 *power1) return IR_DECODE_SUCCEEDED; } -INT8 parse_temp_1(struct tag_head *tag, temp_1 *temp1) +INT8 parse_temp_1(struct tag_head *tag, t_temp_1 *temp1) { UINT16 hex_len = 0; UINT16 i = 0; @@ -222,7 +222,7 @@ INT8 parse_temp_1(struct tag_head *tag, temp_1 *temp1) return IR_DECODE_FAILED; } - string_to_hex_common(tag->pdata, hex_data, hex_len); + string_to_hex_common(tag->p_data, hex_data, hex_len); // parse hex data according to length if (hex_data[0] == hex_len - 1) @@ -276,7 +276,7 @@ INT8 parse_temp_1(struct tag_head *tag, temp_1 *temp1) return IR_DECODE_SUCCEEDED; } -INT8 parse_mode_1(struct tag_head *tag, mode_1 *mode1) +INT8 parse_mode_1(struct tag_head *tag, t_mode_1 *mode1) { UINT16 hex_len = 0; UINT16 trav_offset = 0; @@ -296,7 +296,7 @@ INT8 parse_mode_1(struct tag_head *tag, mode_1 *mode1) return IR_DECODE_FAILED; } - string_to_hex_common(tag->pdata, hex_data, hex_len); + string_to_hex_common(tag->p_data, hex_data, hex_len); // parse hex data to mode1 data structure mode1->len = (UINT8) hex_len; @@ -320,7 +320,7 @@ INT8 parse_mode_1(struct tag_head *tag, mode_1 *mode1) return IR_DECODE_SUCCEEDED; } -INT8 parse_speed_1(struct tag_head *tag, speed_1 *speed1) +INT8 parse_speed_1(struct tag_head *tag, t_speed_1 *speed1) { UINT16 hex_len = 0; UINT16 trav_offset = 0; @@ -340,7 +340,7 @@ INT8 parse_speed_1(struct tag_head *tag, speed_1 *speed1) return IR_DECODE_FAILED; } - string_to_hex_common(tag->pdata, hex_data, hex_len); + string_to_hex_common(tag->p_data, hex_data, hex_len); // parse hex data to speed1 data structure speed1->len = (UINT8) hex_len; @@ -364,7 +364,7 @@ INT8 parse_speed_1(struct tag_head *tag, speed_1 *speed1) return IR_DECODE_SUCCEEDED; } -INT8 parse_swing_1(struct tag_head *tag, swing_1 *swing1, UINT16 swing_count) +INT8 parse_swing_1(struct tag_head *tag, t_swing_1 *swing1, UINT16 swing_count) { UINT16 hex_len = 0; UINT16 trav_offset = 0; @@ -384,12 +384,12 @@ INT8 parse_swing_1(struct tag_head *tag, swing_1 *swing1, UINT16 swing_count) return IR_DECODE_FAILED; } - string_to_hex_common(tag->pdata, hex_data, hex_len); + string_to_hex_common(tag->p_data, hex_data, hex_len); // parse hex data to swing1 data structure swing1->count = swing_count; swing1->len = (UINT8) hex_len; - swing1->comp_data = (tag_comp *) ir_malloc(sizeof(tag_comp) * swing_count); + swing1->comp_data = (t_tag_comp *) ir_malloc(sizeof(t_tag_comp) * swing_count); if (NULL == swing1->comp_data) { ir_free(hex_data); @@ -415,7 +415,7 @@ INT8 parse_swing_1(struct tag_head *tag, swing_1 *swing1, UINT16 swing_count) return IR_DECODE_SUCCEEDED; } -INT8 parse_checksum_byte_typed(UINT8 *csdata, tag_checksum_data *checksum, UINT16 len) +INT8 parse_checksum_byte_typed(UINT8 *csdata, t_tag_checksum_data *checksum, UINT16 len) { checksum->start_byte_pos = csdata[2]; checksum->end_byte_pos = csdata[3]; @@ -434,7 +434,7 @@ INT8 parse_checksum_byte_typed(UINT8 *csdata, tag_checksum_data *checksum, UINT1 return IR_DECODE_SUCCEEDED; } -INT8 parse_checksum_half_byte_typed(UINT8 *csdata, tag_checksum_data *checksum, UINT16 len) +INT8 parse_checksum_half_byte_typed(UINT8 *csdata, t_tag_checksum_data *checksum, UINT16 len) { checksum->start_byte_pos = csdata[2]; checksum->end_byte_pos = csdata[3]; @@ -452,7 +452,7 @@ INT8 parse_checksum_half_byte_typed(UINT8 *csdata, tag_checksum_data *checksum, return IR_DECODE_SUCCEEDED; } -INT8 parse_checksum_spec_half_byte_typed(UINT8 *csdata, tag_checksum_data *checksum, UINT16 len) +INT8 parse_checksum_spec_half_byte_typed(UINT8 *csdata, t_tag_checksum_data *checksum, UINT16 len) { /* * note: @@ -478,14 +478,14 @@ INT8 parse_checksum_spec_half_byte_typed(UINT8 *csdata, tag_checksum_data *check return IR_DECODE_SUCCEEDED; } -INT8 parse_checksum_malloc(struct tag_head *tag, tchecksum *checksum) +INT8 parse_checksum_malloc(struct tag_head *tag, t_checksum *checksum) { UINT8 i = 0; UINT8 cnt = 0; for (i = 0; i < tag->len; i++) { - if (tag->pdata[i] == '|') + if (tag->p_data[i] == '|') { cnt++; } @@ -493,18 +493,18 @@ INT8 parse_checksum_malloc(struct tag_head *tag, tchecksum *checksum) checksum->len = (UINT8) ((tag->len - cnt) >> 1); checksum->count = (UINT16) (cnt + 1); - checksum->checksum_data = (tag_checksum_data *) ir_malloc(sizeof(tag_checksum_data) * checksum->count); + checksum->checksum_data = (t_tag_checksum_data *) ir_malloc(sizeof(t_tag_checksum_data) * checksum->count); if (NULL == checksum->checksum_data) { return IR_DECODE_FAILED; } - ir_memset(checksum->checksum_data, 0x00, sizeof(tag_checksum_data) * checksum->count); + ir_memset(checksum->checksum_data, 0x00, sizeof(t_tag_checksum_data) * checksum->count); return IR_DECODE_SUCCEEDED; } -INT8 parse_checksum_data(UINT8 *buf, tag_checksum_data *checksum, UINT8 length) +INT8 parse_checksum_data(UINT8 *buf, t_tag_checksum_data *checksum, UINT8 length) { UINT8 *hex_data = NULL; UINT16 hex_len = 0; @@ -574,7 +574,7 @@ INT8 parse_checksum_data(UINT8 *buf, tag_checksum_data *checksum, UINT8 length) return IR_DECODE_SUCCEEDED; } -INT8 parse_checksum(struct tag_head *tag, tchecksum *checksum) +INT8 parse_checksum(struct tag_head *tag, t_checksum *checksum) { UINT8 i = 0; UINT8 num = 0; @@ -597,9 +597,9 @@ INT8 parse_checksum(struct tag_head *tag, tchecksum *checksum) for (i = 0; i < tag->len; i++) { - if (tag->pdata[i] == '|') + if (tag->p_data[i] == '|') { - if (IR_DECODE_FAILED == parse_checksum_data(tag->pdata + preindex, + if (IR_DECODE_FAILED == parse_checksum_data(tag->p_data + preindex, checksum->checksum_data + num, (UINT8) (i - preindex) >> 1)) { @@ -610,7 +610,7 @@ INT8 parse_checksum(struct tag_head *tag, tchecksum *checksum) } } - if (IR_DECODE_FAILED == parse_checksum_data(tag->pdata + preindex, + if (IR_DECODE_FAILED == parse_checksum_data(tag->p_data + preindex, checksum->checksum_data + num, (UINT8) (i - preindex) >> 1)) { @@ -620,7 +620,7 @@ INT8 parse_checksum(struct tag_head *tag, tchecksum *checksum) return IR_DECODE_SUCCEEDED; } -INT8 parse_function_1(UINT8 *data, UINT16 *trav_offset, tag_comp *mode_seg) +INT8 parse_function_1(UINT8 *data, UINT16 *trav_offset, t_tag_comp *mode_seg) { UINT8 seg_len = 0; BOOL valid_function_id = TRUE; @@ -687,7 +687,7 @@ INT8 parse_function_1(UINT8 *data, UINT16 *trav_offset, tag_comp *mode_seg) return function_id; } -INT8 parse_function_1_tag29(struct tag_head *tag, function_1 *function1) +INT8 parse_function_1_tag29(struct tag_head *tag, t_function_1 *function1) { UINT16 hex_len = 0; UINT16 trav_offset = 0; @@ -712,7 +712,7 @@ INT8 parse_function_1_tag29(struct tag_head *tag, function_1 *function1) return IR_DECODE_FAILED; } - string_to_hex_common(tag->pdata, hex_data, hex_len); + string_to_hex_common(tag->p_data, hex_data, hex_len); // parse hex data to mode1 data structure function1->len = (UINT8) hex_len; @@ -743,7 +743,7 @@ INT8 parse_function_1_tag29(struct tag_head *tag, function_1 *function1) return IR_DECODE_SUCCEEDED; } -INT8 parse_temp_2(struct tag_head *tag, temp_2 *temp2) +INT8 parse_temp_2(struct tag_head *tag, t_temp_2 *temp2) { UINT16 hex_len = 0; UINT16 i = 0; @@ -769,7 +769,7 @@ INT8 parse_temp_2(struct tag_head *tag, temp_2 *temp2) return IR_DECODE_FAILED; } - string_to_hex_common(tag->pdata, hex_data, hex_len); + string_to_hex_common(tag->p_data, hex_data, hex_len); // parse hex data according to length if (hex_data[0] == hex_len - 1) @@ -823,7 +823,7 @@ INT8 parse_temp_2(struct tag_head *tag, temp_2 *temp2) return IR_DECODE_SUCCEEDED; } -INT8 parse_mode_2(struct tag_head *tag, mode_2 *mode2) +INT8 parse_mode_2(struct tag_head *tag, t_mode_2 *mode2) { UINT16 hex_len = 0; UINT16 trav_offset = 0; @@ -848,7 +848,7 @@ INT8 parse_mode_2(struct tag_head *tag, mode_2 *mode2) return IR_DECODE_FAILED; } - string_to_hex_common(tag->pdata, hex_data, hex_len); + string_to_hex_common(tag->p_data, hex_data, hex_len); // parse hex data to mode1 data structure mode2->len = (UINT8) hex_len; @@ -872,7 +872,7 @@ INT8 parse_mode_2(struct tag_head *tag, mode_2 *mode2) return IR_DECODE_SUCCEEDED; } -INT8 parse_speed_2(struct tag_head *tag, speed_2 *speed2) +INT8 parse_speed_2(struct tag_head *tag, t_speed_2 *speed2) { UINT16 hex_len = 0; UINT16 trav_offset = 0; @@ -897,7 +897,7 @@ INT8 parse_speed_2(struct tag_head *tag, speed_2 *speed2) return IR_DECODE_FAILED; } - string_to_hex_common(tag->pdata, hex_data, hex_len); + string_to_hex_common(tag->p_data, hex_data, hex_len); // parse hex data to speed1 data structure speed2->len = (UINT8) hex_len; @@ -921,7 +921,7 @@ INT8 parse_speed_2(struct tag_head *tag, speed_2 *speed2) return IR_DECODE_SUCCEEDED; } -INT8 parse_swing_2(struct tag_head *tag, swing_2 *swing2, UINT16 swing_count) +INT8 parse_swing_2(struct tag_head *tag, t_swing_2 *swing2, UINT16 swing_count) { UINT16 hex_len = 0; UINT16 trav_offset = 0; @@ -946,12 +946,12 @@ INT8 parse_swing_2(struct tag_head *tag, swing_2 *swing2, UINT16 swing_count) return IR_DECODE_FAILED; } - string_to_hex_common(tag->pdata, hex_data, hex_len); + string_to_hex_common(tag->p_data, hex_data, hex_len); // parse hex data to swing2 data structure swing2->count = swing_count; swing2->len = (UINT8) hex_len; - swing2->comp_data = (tag_comp *) ir_malloc(sizeof(tag_comp) * swing_count); + swing2->comp_data = (t_tag_comp *) ir_malloc(sizeof(t_tag_comp) * swing_count); if (NULL == swing2->comp_data) { ir_free(hex_data); @@ -977,7 +977,7 @@ INT8 parse_swing_2(struct tag_head *tag, swing_2 *swing2, UINT16 swing_count) return IR_DECODE_SUCCEEDED; } -INT8 parse_function_2(UINT8 *data, UINT16 *trav_offset, tag_comp *mode_seg) +INT8 parse_function_2(UINT8 *data, UINT16 *trav_offset, t_tag_comp *mode_seg) { UINT8 seg_len = 0; BOOL valid_function_id = TRUE; @@ -1045,7 +1045,7 @@ INT8 parse_function_2(UINT8 *data, UINT16 *trav_offset, tag_comp *mode_seg) return function_id; } -INT8 parse_function_2_tag34(struct tag_head *tag, function_2 *function2) +INT8 parse_function_2_tag34(struct tag_head *tag, t_function_2 *function2) { UINT16 hex_len = 0; UINT16 trav_offset = 0; @@ -1070,7 +1070,7 @@ INT8 parse_function_2_tag34(struct tag_head *tag, function_2 *function2) return IR_DECODE_FAILED; } - string_to_hex_common(tag->pdata, hex_data, hex_len); + string_to_hex_common(tag->p_data, hex_data, hex_len); // parse hex data to mode1 data structure function2->len = (UINT8) hex_len; @@ -1101,7 +1101,7 @@ INT8 parse_function_2_tag34(struct tag_head *tag, function_2 *function2) return IR_DECODE_SUCCEEDED; } -INT8 parse_swing_info(struct tag_head *tag, swing_info *si) +INT8 parse_swing_info(struct tag_head *tag, t_swing_info *si) { if (NULL == tag) { @@ -1117,13 +1117,13 @@ INT8 parse_swing_info(struct tag_head *tag, swing_info *si) */ if (1 == tag->len) { - if ('0' == tag->pdata[0]) + if ('0' == tag->p_data[0]) { // to identify if there is only 1 status in TAG 26 OR 33 si->type = SWING_TYPE_NOT_SPECIFIED; si->mode_count = 0; } - else if ('1' == tag->pdata[0]) + else if ('1' == tag->p_data[0]) { si->type = SWING_TYPE_SWING_ONLY; si->mode_count = 1; @@ -1145,7 +1145,7 @@ INT8 parse_swing_info(struct tag_head *tag, swing_info *si) return IR_DECODE_SUCCEEDED; } -INT8 parse_solo_code(struct tag_head *tag, solo_code *sc) +INT8 parse_solo_code(struct tag_head *tag, t_solo_code *sc) { UINT16 hex_len = 0; UINT8 *hex_data = NULL; @@ -1175,7 +1175,7 @@ INT8 parse_solo_code(struct tag_head *tag, solo_code *sc) { return IR_DECODE_FAILED; } - string_to_hex_common(tag->pdata, hex_data, hex_len); + string_to_hex_common(tag->p_data, hex_data, hex_len); // parse hex data to mode1 data structure sc->len = (UINT8) hex_len; diff --git a/cc26xx-example/ti/BLE-CC264x/ble_cc26xx/Projects/ble/SimpleBLEPeripheral-IREXT/CC26xx/Source/Application/Irext/src/ir_decode.c b/cc26xx-example/ti/BLE-CC264x/ble_cc26xx/Projects/ble/SimpleBLEPeripheral-IREXT/CC26xx/Source/Application/Irext/src/ir_decode.c index cfc7b5b..f2b8cdd 100644 --- a/cc26xx-example/ti/BLE-CC264x/ble_cc26xx/Projects/ble/SimpleBLEPeripheral-IREXT/CC26xx/Source/Application/Irext/src/ir_decode.c +++ b/cc26xx-example/ti/BLE-CC264x/ble_cc26xx/Projects/ble/SimpleBLEPeripheral-IREXT/CC26xx/Source/Application/Irext/src/ir_decode.c @@ -35,7 +35,7 @@ UINT8 *binary_content = NULL; UINT8 ir_binary_type = IR_TYPE_STATUS; UINT8 ir_hexadecimal = SUB_CATEGORY_QUATERNARY; -protocol *context = (protocol *) byteArray; +t_ac_protocol *context = (t_ac_protocol *) byteArray; lp_apply_ac_parameter apply_table[AC_APPLY_MAX] = { @@ -51,7 +51,7 @@ lp_apply_ac_parameter apply_table[AC_APPLY_MAX] = // static functions declarations static INT8 ir_ac_file_open(const char *file_name); static INT8 ir_ac_lib_open(UINT8 *binary, UINT16 binary_length); -static UINT16 ir_ac_lib_control(remote_ac_status_t ac_status, UINT16 *user_data, UINT8 function_code, +static UINT16 ir_ac_lib_control(t_remote_ac_status ac_status, UINT16 *user_data, UINT8 function_code, BOOL change_wind_direction); static INT8 ir_ac_lib_close(); static INT8 ir_tv_file_open(const char *file_name); @@ -159,7 +159,7 @@ INT8 ir_binary_open(const UINT8 category, const UINT8 sub_category, UINT8* binar } -UINT16 ir_decode(UINT8 key_code, UINT16* user_data, remote_ac_status_t* ac_status, BOOL change_wind_direction) +UINT16 ir_decode(UINT8 key_code, UINT16* user_data, t_remote_ac_status* ac_status, BOOL change_wind_direction) { if (IR_TYPE_COMMANDS == ir_binary_type) { @@ -257,7 +257,7 @@ static INT8 ir_ac_lib_open(UINT8 *binary, UINT16 binary_length) return IR_DECODE_SUCCEEDED; } -static UINT16 ir_ac_lib_control(remote_ac_status_t ac_status, UINT16 *user_data, UINT8 function_code, +static UINT16 ir_ac_lib_control(t_remote_ac_status ac_status, UINT16 *user_data, UINT8 function_code, BOOL change_wind_direction) { UINT16 time_length = 0; @@ -281,7 +281,7 @@ static UINT16 ir_ac_lib_control(remote_ac_status_t ac_status, UINT16 *user_data, ir_memcpy(ir_hex_code, context->default_code.data, context->default_code.len); #if defined USE_APPLY_TABLE - if(ac_status.acPower != AC_POWER_OFF) + if(ac_status.ac_power != AC_POWER_OFF) { for (i = AC_APPLY_POWER; i < AC_APPLY_MAX; i++) { @@ -289,7 +289,7 @@ static UINT16 ir_ac_lib_control(remote_ac_status_t ac_status, UINT16 *user_data, } } #else - if (ac_status.acPower == AC_POWER_OFF) + if (ac_status.ac_power == AC_POWER_OFF) { // otherwise, power should always be applied apply_power(ac_status, function_code); @@ -297,7 +297,7 @@ static UINT16 ir_ac_lib_control(remote_ac_status_t ac_status, UINT16 *user_data, else { // check the mode as the first priority, despite any other status - if (TRUE == context->n_mode[ac_status.acMode].enable) + if (TRUE == context->n_mode[ac_status.ac_mode].enable) { if (is_solo_function(function_code)) { @@ -400,7 +400,7 @@ INT8 get_temperature_range(UINT8 ac_mode, INT8 *temp_min, INT8 *temp_max) return IR_DECODE_FAILED; } - if (1 == context->n_mode[ac_mode].alltemp) + if (1 == context->n_mode[ac_mode].all_temp) { *temp_min = *temp_max = -1; return IR_DECODE_SUCCEEDED; @@ -410,7 +410,7 @@ INT8 get_temperature_range(UINT8 ac_mode, INT8 *temp_min, INT8 *temp_max) *temp_max = -1; for (i = 0; i < AC_TEMP_MAX; i++) { - if (isin(context->n_mode[ac_mode].temp, i, context->n_mode[ac_mode].temp_cnt) || + if (is_in(context->n_mode[ac_mode].temp, i, context->n_mode[ac_mode].temp_cnt) || (context->temp1.len != 0 && 0 == context->temp1.comp_data[i].seg_len) || (context->temp2.len != 0 && 0 == context->temp2.comp_data[i].seg_len)) { @@ -463,7 +463,7 @@ INT8 get_supported_wind_speed(UINT8 ac_mode, UINT8 *supported_wind_speed) return IR_DECODE_FAILED; } - if (1 == context->n_mode[ac_mode].allspeed) + if (1 == context->n_mode[ac_mode].all_speed) { *supported_wind_speed = 0; return IR_DECODE_SUCCEEDED; @@ -473,7 +473,7 @@ INT8 get_supported_wind_speed(UINT8 ac_mode, UINT8 *supported_wind_speed) for (i = 0; i < AC_WS_MAX; i++) { - if (isin(context->n_mode[ac_mode].speed, i, context->n_mode[ac_mode].speed_cnt) || + if (is_in(context->n_mode[ac_mode].speed, i, context->n_mode[ac_mode].speed_cnt) || (context->speed1.len != 0 && 0 == context->speed1.comp_data[i].seg_len) || (context->speed2.len != 0 && 0 == context->speed2.comp_data[i].seg_len)) { diff --git a/cc26xx-example/ti/BLE-CC264x/ble_cc26xx/Projects/ble/SimpleBLEPeripheral-IREXT/CC26xx/Source/Application/Irext/src/ir_tv_control.c b/cc26xx-example/ti/BLE-CC264x/ble_cc26xx/Projects/ble/SimpleBLEPeripheral-IREXT/CC26xx/Source/Application/Irext/src/ir_tv_control.c index e4b04ba..78cb9b9 100644 --- a/cc26xx-example/ti/BLE-CC264x/ble_cc26xx/Projects/ble/SimpleBLEPeripheral-IREXT/CC26xx/Source/Application/Irext/src/ir_tv_control.c +++ b/cc26xx-example/ti/BLE-CC264x/ble_cc26xx/Projects/ble/SimpleBLEPeripheral-IREXT/CC26xx/Source/Application/Irext/src/ir_tv_control.c @@ -26,12 +26,11 @@ struct buffer static struct buffer *pbuffer = &ir_file; -//static UINT8 *prot_name = NULL; static UINT8 *prot_cycles_num = NULL; -static ir_cycles_t *prot_cycles_data[IRDA_MAX]; +static t_ir_cycles *prot_cycles_data[IRDA_MAX]; static UINT8 prot_items_cnt = 0; -static ir_data_t *prot_items_data = NULL; -static ir_data_tv_t *remote_p; +static t_ir_data *prot_items_data = NULL; +static t_ir_data_tv *remote_p; static UINT8 *remote_pdata = NULL; static UINT16 time_index = 0; @@ -45,13 +44,13 @@ static BOOL get_ir_protocol(UINT8 encode_type); static BOOL get_ir_keymap(void); -static void print_ir_time(ir_data_t *data, UINT8 key_index, UINT16 *ir_time); +static void print_ir_time(t_ir_data *data, UINT8 key_index, UINT16 *ir_time); -static void process_decode_number(UINT8 keycode, ir_data_t *data, UINT8 valid_bits, UINT16 *ir_time); +static void process_decode_number(UINT8 keycode, t_ir_data *data, UINT8 valid_bits, UINT16 *ir_time); static void convert_to_ir_time(UINT8 value, UINT16 *ir_time); -static void replace_with(ir_cycles_t *pcycles_num, UINT16 *ir_time); +static void replace_with(t_ir_cycles *pcycles_num, UINT16 *ir_time); INT8 tv_lib_open(UINT8 *binary, UINT16 binary_length) @@ -109,8 +108,7 @@ static BOOL get_ir_protocol(UINT8 encode_type) pbuffer->offset = 0; - /* protocol name */ - // prot_name = pbuffer->data + pbuffer->offset; + /* t_ac_protocol name */ pbuffer->offset += name_size; /* cycles number */ @@ -145,7 +143,7 @@ static BOOL get_ir_protocol(UINT8 encode_type) { if (0 != prot_cycles_num[i]) { - prot_cycles_data[i] = (ir_cycles_t *) (&prot_cycles[sizeof(ir_cycles_t) * cycles_sum]); + prot_cycles_data[i] = (t_ir_cycles *) (&prot_cycles[sizeof(t_ir_cycles) * cycles_sum]); } else { @@ -153,15 +151,15 @@ static BOOL get_ir_protocol(UINT8 encode_type) } cycles_sum += prot_cycles_num[i]; } - pbuffer->offset += sizeof(ir_cycles_t) * cycles_sum; + pbuffer->offset += sizeof(t_ir_cycles) * cycles_sum; /* items count */ prot_items_cnt = pbuffer->data[pbuffer->offset]; pbuffer->offset += sizeof(UINT8); /* items data */ - prot_items_data = (ir_data_t *) (pbuffer->data + pbuffer->offset); - pbuffer->offset += prot_items_cnt * sizeof(ir_data_t); + prot_items_data = (t_ir_data *) (pbuffer->data + pbuffer->offset); + pbuffer->offset += prot_items_cnt * sizeof(t_ir_data); ir_toggle_bit = FALSE; @@ -170,8 +168,8 @@ static BOOL get_ir_protocol(UINT8 encode_type) static BOOL get_ir_keymap(void) { - remote_p = (ir_data_tv_t *) (pbuffer->data + pbuffer->offset); - pbuffer->offset += sizeof(ir_data_tv_t); + remote_p = (t_ir_data_tv *) (pbuffer->data + pbuffer->offset); + pbuffer->offset += sizeof(t_ir_data_tv); if (strncmp(remote_p->magic, "irda", 4) == 0) { @@ -182,11 +180,11 @@ static BOOL get_ir_keymap(void) return FALSE; } -static void print_ir_time(ir_data_t *data, UINT8 key_index, UINT16 *ir_time) +static void print_ir_time(t_ir_data *data, UINT8 key_index, UINT16 *ir_time) { UINT8 i = 0; UINT8 cycles_num = 0; - ir_cycles_t *pcycles = NULL; + t_ir_cycles *pcycles = NULL; UINT8 key_code = 0; if (NULL == data || NULL == ir_time) @@ -301,10 +299,7 @@ static void print_ir_time(ir_data_t *data, UINT8 key_index, UINT16 *ir_time) { break; } - else - { - pcycles++; - } + pcycles++; } } else @@ -331,7 +326,7 @@ static void print_ir_time(ir_data_t *data, UINT8 key_index, UINT16 *ir_time) } } -static void process_decode_number(UINT8 keycode, ir_data_t *data, UINT8 valid_bits, UINT16 *ir_time) +static void process_decode_number(UINT8 keycode, t_ir_data *data, UINT8 valid_bits, UINT16 *ir_time) { UINT8 i = 0; UINT8 value = 0; @@ -415,7 +410,7 @@ static void convert_to_ir_time(UINT8 value, UINT16 *ir_time) } } -static void replace_with(ir_cycles_t *pcycles_num, UINT16 *ir_time) +static void replace_with(t_ir_cycles *pcycles_num, UINT16 *ir_time) { if (NULL == pcycles_num || NULL == ir_time) { diff --git a/cc26xx-example/ti/BLE-CC264x/ble_cc26xx/Projects/ble/SimpleBLEPeripheral-IREXT/CC26xx/Source/Application/Irext/src/ir_utils.c b/cc26xx-example/ti/BLE-CC264x/ble_cc26xx/Projects/ble/SimpleBLEPeripheral-IREXT/CC26xx/Source/Application/Irext/src/ir_utils.c index bbe78c6..6867df7 100644 --- a/cc26xx-example/ti/BLE-CC264x/ble_cc26xx/Projects/ble/SimpleBLEPeripheral-IREXT/CC26xx/Source/Application/Irext/src/ir_utils.c +++ b/cc26xx-example/ti/BLE-CC264x/ble_cc26xx/Projects/ble/SimpleBLEPeripheral-IREXT/CC26xx/Source/Application/Irext/src/ir_utils.c @@ -23,7 +23,7 @@ UINT8 char_to_hex(char chr) return value; } -UINT8 chars_to_hex(UINT8 *p) +UINT8 chars_to_hex(const UINT8 *p) { return (char_to_hex(*p) << 4) + char_to_hex(*(p + 1)); } @@ -40,7 +40,7 @@ void string_to_hex_common(UINT8 *p, UINT8 *hex_data, UINT16 len) } } -void string_to_hex(UINT8 *p, ac_hex *pac_hex, UINT16 len) +void string_to_hex(UINT8 *p, t_ac_hex *pac_hex) { UINT8 i = 0; @@ -84,7 +84,7 @@ void hex_byte_to_double_char(char *dest, UINT8 length, UINT8 src) dest[1] = hex_half_byte_to_single_char(1, lo_num); } -BOOL isin(UINT8 array[], UINT8 value, UINT8 len) +BOOL is_in(const UINT8 *array, UINT8 value, UINT8 len) { UINT16 i = 0; for (i = 0; i < len; i++) diff --git a/cc26xx-example/ti/BLE-CC264x/ble_cc26xx/Projects/ble/SimpleBLEPeripheral-IREXT/CC26xx/Source/Application/simpleBLEPeripheral.c b/cc26xx-example/ti/BLE-CC264x/ble_cc26xx/Projects/ble/SimpleBLEPeripheral-IREXT/CC26xx/Source/Application/simpleBLEPeripheral.c index ef931a8..f57a7f6 100644 --- a/cc26xx-example/ti/BLE-CC264x/ble_cc26xx/Projects/ble/SimpleBLEPeripheral-IREXT/CC26xx/Source/Application/simpleBLEPeripheral.c +++ b/cc26xx-example/ti/BLE-CC264x/ble_cc26xx/Projects/ble/SimpleBLEPeripheral-IREXT/CC26xx/Source/Application/simpleBLEPeripheral.c @@ -140,16 +140,16 @@ static decode_control_block dccb = .decoded_length = 0, }; -static remote_ac_status_t ac_status = +static t_remote_ac_status ac_status = { - .acPower = AC_POWER_OFF, - .acTemp = AC_TEMP_24, - .acMode = AC_MODE_COOL, - .acWindDir = AC_SWING_ON, - .acWindSpeed = AC_WS_AUTO, - .acDisplay = 0, - .acSleep = 0, - .acTimer = 0, + .ac_power = AC_POWER_OFF, + .ac_temp = AC_TEMP_24, + .ac_mode = AC_MODE_COOL, + .ac_wind_dir = AC_SWING_ON, + .ac_wind_speed = AC_WS_AUTO, + .ac_display = 0, + .ac_sleep = 0, + .ac_timer = 0, }; diff --git a/pi3-smart-remote/.idea/misc.xml b/pi3-smart-remote/.idea/misc.xml index 5d19981..f3d13dd 100644 --- a/pi3-smart-remote/.idea/misc.xml +++ b/pi3-smart-remote/.idea/misc.xml @@ -27,17 +27,7 @@ - - - - - - - - - - - + diff --git a/pi3-smart-remote/app/build.gradle b/pi3-smart-remote/app/build.gradle index a46b939..f002f37 100644 --- a/pi3-smart-remote/app/build.gradle +++ b/pi3-smart-remote/app/build.gradle @@ -2,7 +2,7 @@ apply plugin: 'com.android.application' android { compileSdkVersion 26 - buildToolsVersion "26.0.0" + buildToolsVersion '26.0.2' defaultConfig { applicationId "net.irext.pi3sr" minSdkVersion 25 @@ -21,6 +21,7 @@ android { dependencies { compile fileTree(dir: 'libs', include: ['*.jar']) + provided 'com.google.android.things:androidthings:0.5.1-devpreview' compile 'com.android.support:appcompat-v7:26.+' compile 'com.android.support.constraint:constraint-layout:1.0.0-beta4' } diff --git a/pi3-smart-remote/app/src/main/AndroidManifest.xml b/pi3-smart-remote/app/src/main/AndroidManifest.xml index 5fd0694..1aaabc2 100644 --- a/pi3-smart-remote/app/src/main/AndroidManifest.xml +++ b/pi3-smart-remote/app/src/main/AndroidManifest.xml @@ -12,7 +12,7 @@ - + diff --git a/pi3-smart-remote/app/src/main/java/net/irext/pi3sr/Pi3SRApplication.java b/pi3-smart-remote/app/src/main/java/net/irext/pi3sr/Pi3SRApplication.java new file mode 100644 index 0000000..82c5cca --- /dev/null +++ b/pi3-smart-remote/app/src/main/java/net/irext/pi3sr/Pi3SRApplication.java @@ -0,0 +1,13 @@ +package net.irext.pi3sr; + +import android.app.Application; + +/** + * + * Pi3SRApplication + * + * created by strawmanbobi 2017-06-25 + */ +public class Pi3SRApplication extends Application { + +} diff --git a/pi3-smart-remote/app/src/main/java/net/irext/pi3sr/driver/HCSR501.java b/pi3-smart-remote/app/src/main/java/net/irext/pi3sr/driver/HCSR501.java new file mode 100644 index 0000000..74b958f --- /dev/null +++ b/pi3-smart-remote/app/src/main/java/net/irext/pi3sr/driver/HCSR501.java @@ -0,0 +1,63 @@ +package net.irext.pi3sr.driver; + +import android.util.Log; + +import com.google.android.things.pio.Gpio; +import com.google.android.things.pio.GpioCallback; + +import java.io.IOException; + +/** + * + * HC-SR501 driver + * + * created by strawmanbobi 2017-06-25 + */ +public class HCSR501 implements MotionSensor { + + private static final String TAG = HCSR501.class.getSimpleName(); + + private final Gpio bus; + + private final MotionSensor.Listener listener; + + public HCSR501(Gpio bus, Listener listener) { + this.bus = bus; + this.listener = listener; + } + + @Override + public void startup() { + try { + bus.setDirection(Gpio.DIRECTION_IN); + bus.setActiveType(Gpio.ACTIVE_HIGH); + bus.setEdgeTriggerType(Gpio.EDGE_RISING); + } catch (IOException e) { + throw new IllegalStateException("Sensor can't start - App is foobar'd", e); + } + try { + bus.registerGpioCallback(callback); + } catch (IOException e) { + throw new IllegalStateException("Sensor can't register callback", e); + } + } + + private final GpioCallback callback = new GpioCallback() { + @Override + public boolean onGpioEdge(Gpio gpio) { + listener.onMovement(); + return true; + } + }; + + @Override + public void shutdown() { + bus.unregisterGpioCallback(callback); + try { + bus.close(); + } catch (IOException e) { + Log.e(TAG, "Failed to shut down. You might get errors next time you try to start.", e); + } + } + +} diff --git a/pi3-smart-remote/app/src/main/java/net/irext/pi3sr/driver/MotionSensor.java b/pi3-smart-remote/app/src/main/java/net/irext/pi3sr/driver/MotionSensor.java new file mode 100644 index 0000000..c02676d --- /dev/null +++ b/pi3-smart-remote/app/src/main/java/net/irext/pi3sr/driver/MotionSensor.java @@ -0,0 +1,19 @@ +package net.irext.pi3sr.driver; + +/** + * + * motion sensor interface + * + * created by strawmanbobi 2017-06-25 + */ +public interface MotionSensor { + + void startup(); + + void shutdown(); + + public interface Listener { + void onMovement(); + } + +} diff --git a/pi3-smart-remote/app/src/main/java/net/irext/pi3sr/MainActivity.java b/pi3-smart-remote/app/src/main/java/net/irext/pi3sr/ui/MainActivity.java similarity index 71% rename from pi3-smart-remote/app/src/main/java/net/irext/pi3sr/MainActivity.java rename to pi3-smart-remote/app/src/main/java/net/irext/pi3sr/ui/MainActivity.java index c1546c5..dcaf926 100644 --- a/pi3-smart-remote/app/src/main/java/net/irext/pi3sr/MainActivity.java +++ b/pi3-smart-remote/app/src/main/java/net/irext/pi3sr/ui/MainActivity.java @@ -1,8 +1,16 @@ -package net.irext.pi3sr; +package net.irext.pi3sr.ui; import android.support.v7.app.AppCompatActivity; import android.os.Bundle; +import net.irext.pi3sr.R; + +/** + * + * MainActivity + * + * created by strawmanbobi 2017-06-25 + */ public class MainActivity extends AppCompatActivity { @Override diff --git a/pi3-smart-remote/app/src/main/res/layout/activity_main.xml b/pi3-smart-remote/app/src/main/res/layout/activity_main.xml index 2eb84cf..722a2e0 100644 --- a/pi3-smart-remote/app/src/main/res/layout/activity_main.xml +++ b/pi3-smart-remote/app/src/main/res/layout/activity_main.xml @@ -4,7 +4,7 @@ xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" - tools:context="net.irext.pi3sr.MainActivity"> + tools:context="net.irext.pi3sr.ui.MainActivity"> ) +# find_package(AndroidThings REQUIRED) +# include_directories(${ANDROIDTHINGS_INCLUDE_DIRS}) +# target_link_libraries( ${ANDROIDTHINGS_LIBRARIES}) +# +# Finding the Source +# ------------------ +# Normally the libandroidthings headers and .so are expected to live in the +# same directory as this file, but if the ANDROIDTHINGS_DIR variable is +# provided in the app's build.gradle file, that path will be searched for the +# headers and .so first. For example: +# +# android { +# defaultConfig { +# externalNativeBuild { +# cmake { +# arguments "-DANDROIDTHINGS_DIR=" +# } +# } +# } +# +# ABI Specification +# ----------------- +# libandroidthings is only available for the ABIs supported by Android Things +# devices. By default, Android Studio attempts to build for all ABIs, which may +# lead to errors like: +# +# Could NOT find AndroidThings (missing: ANDROIDTHINGS_LIBRARY +# ANDROIDTHINGS_INCLUDE_DIR) +# +# To work around this, you will need to modify your app's build.gradle to +# only build the ABIs you need: +# +# android { +# defaultConfig { +# externalNativeBuild { +# cmake { +# abiFilters "", "", ... +# } +# } +# } + + +# Find the libandroidthings header files. +find_path(ANDROIDTHINGS_INCLUDE_DIR + NAMES pio/peripheral_manager_client.h + HINTS "${ANDROIDTHINGS_DIR}" "${CMAKE_CURRENT_LIST_DIR}" + PATH_SUFFIXES "${ANDROID_ABI}/include" + NO_CMAKE_FIND_ROOT_PATH) + +# Find the libandroidthings.so library. +find_library(ANDROIDTHINGS_LIBRARY + NAMES libandroidthings.so + HINTS "${ANDROIDTHINGS_DIR}" "${CMAKE_CURRENT_LIST_DIR}" + PATH_SUFFIXES "${ANDROID_ABI}/lib" + NO_CMAKE_FIND_ROOT_PATH) + +# Register the package and set ANDROIDTHINGS_FOUND. +include(FindPackageHandleStandardArgs) +find_package_handle_standard_args(AndroidThings DEFAULT_MSG + ANDROIDTHINGS_LIBRARY + ANDROIDTHINGS_INCLUDE_DIR) + +# Hide these variables by default. +mark_as_advanced(ANDROIDTHINGS_INCLUDE_DIR ANDROIDTHINGS_LIBRARY) + +# Set the remaining variables we want to export. +set(ANDROIDTHINGS_LIBRARIES ${ANDROIDTHINGS_LIBRARY}) +set(ANDROIDTHINGS_INCLUDE_DIRS ${ANDROIDTHINGS_INCLUDE_DIR}) +set(ANDROIDTHINGS_DEFINITIONS "") + diff --git a/pi3-smart-remote/native-libandroidthings-0.5.1-devpreview/LICENSE b/pi3-smart-remote/native-libandroidthings-0.5.1-devpreview/LICENSE new file mode 100644 index 0000000..1af981f --- /dev/null +++ b/pi3-smart-remote/native-libandroidthings-0.5.1-devpreview/LICENSE @@ -0,0 +1,201 @@ + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright 2014 The Android Open Source Project + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. diff --git a/pi3-smart-remote/native-libandroidthings-0.5.1-devpreview/README.md b/pi3-smart-remote/native-libandroidthings-0.5.1-devpreview/README.md new file mode 100644 index 0000000..29d34cb --- /dev/null +++ b/pi3-smart-remote/native-libandroidthings-0.5.1-devpreview/README.md @@ -0,0 +1,47 @@ +Android Things Native Library +============================= + +This repository contains the symbols and the headers for the Android Things +[Native PIO API](https://developer.android.com/things/sdk/pio/native.html) for the following architecture: +- `armeabi-v7a` +- `x86` + +Usage +===== + +- Unzip the latest [release](https://github.com/androidthings/native-libandroidthings/releases) in the native project directory (or in a shared location if you have many native projects). +- Add the following lines to the native project `CMakeLists.txt`: +``` +set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} ) +find_package(AndroidThings REQUIRED) +include_directories(${ANDROIDTHINGS_INCLUDE_DIRS}) +target_link_libraries( ${ANDROIDTHINGS_LIBRARIES}) +``` +- Add the following arch to the native module `build.gradle`: +``` +defaultConfig { + ndk { + abiFilters 'armeabi-v7a', 'x86' + } +} +``` + +License +======= + +Copyright 2016 The Android Open Source Project, Inc. + +Licensed to the Apache Software Foundation (ASF) under one or more contributor +license agreements. See the NOTICE file distributed with this work for +additional information regarding copyright ownership. The ASF licenses this +file to you under the Apache License, Version 2.0 (the "License"); you may not +use this file except in compliance with the License. You may obtain a copy of +the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +License for the specific language governing permissions and limitations under +the License. diff --git a/pi3-smart-remote/native-libandroidthings-0.5.1-devpreview/armeabi-v7a/include/pio/gpio.h b/pi3-smart-remote/native-libandroidthings-0.5.1-devpreview/armeabi-v7a/include/pio/gpio.h new file mode 100644 index 0000000..653a4fe --- /dev/null +++ b/pi3-smart-remote/native-libandroidthings-0.5.1-devpreview/armeabi-v7a/include/pio/gpio.h @@ -0,0 +1,107 @@ +/* + * Copyright (C) 2016 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef SYSTEM_PERIPHERALMANAGER_GPIO_H_ +#define SYSTEM_PERIPHERALMANAGER_GPIO_H_ + +#include +#include + +__BEGIN_DECLS + +/// @defgroup Gpio Gpio Interface +/// @brief Functions to control GPIO pins. +/// +/// These functions can be used to control GPIO. +/// @{ + +/// Edge trigger types. +typedef enum AGpioEdge { + AGPIO_EDGE_NONE = 0, /**< None */ + AGPIO_EDGE_RISING = 1, /**< Rising edge */ + AGPIO_EDGE_FALLING = 2, /**< Falling edge */ + AGPIO_EDGE_BOTH = 3 /**< Both edges */ +} AGpioEdge; + +/// GPIO direction types. +typedef enum AGpioDirection { + AGPIO_DIRECTION_IN = 0, /**< Input mode */ + AGPIO_DIRECTION_OUT_INITIALLY_HIGH = 1, /**< Output mode, initially high */ + AGPIO_DIRECTION_OUT_INITIALLY_LOW = 2 /**< Output mode, initially low */ +} AGpioDirection; + +/// Possible active types. +typedef enum AGpioActiveType { + AGPIO_ACTIVE_LOW = 0, /**< Active Low */ + AGPIO_ACTIVE_HIGH = 1 /**< Active High */ +} AGpioActiveType; + +typedef struct AGpio AGpio; + +/// Sets the GPIO direction to output. +/// @param gpio Pointer to the AGpio struct +/// @param direction One of DIRECTION_IN, +/// DIRECTION_OUT_INITIALLY_HIGH, DIRECTION_OUT_INITIALLY_LOW. +/// @return 0 on success, errno on error. +int AGpio_setDirection(const AGpio* gpio, AGpioDirection direction); + +/// Sets the interrupt edge trigger type. +/// @param gpio Pointer to the AGpio struct +/// @param type One of NONE_EDGE, RISING_EDGE, FALLING_EDGE or BOTH_EDGE. +/// @return 0 on success, errno on error. +int AGpio_setEdgeTriggerType(const AGpio* gpio, AGpioEdge type); + +/// Sets the GPIO’s active low/high status. +/// @param gpio Pointer to the AGpio struct. +/// @param type One of ACTIVE_HIGH, ACTIVE_LOW. +/// @return 0 on success, errno on error. +int AGpio_setActiveType(const AGpio* gpio, AGpioActiveType type); + +/// Sets the GPIO value (for output GPIO only). +/// @param gpio Pointer to the AGpio struct. +/// @param value Value to set. +/// @return 0 on success, errno on error. +int AGpio_setValue(const AGpio* gpio, int value); + +/// Gets the GPIO value (for input GPIO only). +/// @param gpio Pointer to the AGpio struct. +/// @param value Output pointer to the value of the GPIO. +/// @return 0 on success, errno on error. +int AGpio_getValue(const AGpio* gpio, int* value); + +/// Returns a file descriptor that can be used to poll on new data. +/// Can be passed to select/epoll to wait for data to become available. +/// @param gpio Pointer to the AGpio struct. +/// @param fd Output pointer to the file descriptor number. +/// @return 0 on success, errno on error. +int AGpio_getPollingFd(const AGpio* gpio, int* fd); + +/// Acknowledges the interrupt and resets the file descriptor. +/// This must be called after each event triggers in order to be able to +/// poll/select for another event. +/// @param fd Polling file descriptor to reset. +/// @return 0 on success, errno on error. +int AGpio_ackInterruptEvent(int fd); + +/// Destroys a AGpio struct. +/// @param gpio Pointer to the AGpio struct. +void AGpio_delete(AGpio* gpio); + +/// @} + +__END_DECLS + +#endif // SYSTEM_PERIPHERALMANAGER_GPIO_H_ diff --git a/pi3-smart-remote/native-libandroidthings-0.5.1-devpreview/armeabi-v7a/include/pio/i2c_device.h b/pi3-smart-remote/native-libandroidthings-0.5.1-devpreview/armeabi-v7a/include/pio/i2c_device.h new file mode 100644 index 0000000..8a5d890 --- /dev/null +++ b/pi3-smart-remote/native-libandroidthings-0.5.1-devpreview/armeabi-v7a/include/pio/i2c_device.h @@ -0,0 +1,109 @@ +/* + * Copyright (C) 2016 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef SYSTEM_PERIPHERALMANAGER_I2C_DEVICE_H_ +#define SYSTEM_PERIPHERALMANAGER_I2C_DEVICE_H_ + +#include +#include + +__BEGIN_DECLS + +/// @defgroup I2c I2c device interface +/// @brief Functions to control an I2C device. +/// +/// These functions can be used to control an I2C device. +/// @{ + +typedef struct AI2cDevice AI2cDevice; + +/// Reads from the device. +/// @param device Pointer to the AI2cDevice struct. +/// @param data Output buffer to write the data to. +/// @param len Number of bytes to read. +/// @return 0 on success, errno on error +int AI2cDevice_read(const AI2cDevice* device, void* data, uint32_t len); + +/// Reads a byte from an I2C register. +/// @param device Pointer to the AI2cDevice struct. +/// @param reg Register to read from. +/// @param val Output pointer to value to read. +/// @return 0 on success, errno on error +int AI2cDevice_readRegByte(const AI2cDevice* device, uint8_t reg, uint8_t* val); + +/// Reads a word from an I2C register. +/// @param device Pointer to the AI2cDevice struct. +/// @param reg Register to read from. +/// @param val Output pointer to value to read. +/// @return 0 on success, errno on error +int AI2cDevice_readRegWord(const AI2cDevice* device, + uint8_t reg, + uint16_t* val); + +/// Reads from an I2C register. +/// @param device Pointer to the AI2cDevice struct. +/// @param reg Register to read from. +/// @param data Output buffer to write the data to. +/// @param len Number of bytes to read. +/// @return 0 on success, errno on error +int AI2cDevice_readRegBuffer(const AI2cDevice* device, + uint8_t reg, + void* data, + uint32_t len); + +/// Writes to the device. +/// @param device Pointer to the AI2cDevice struct. +/// @param data Buffer to write. +/// @param len Number of bytes to write. +/// @return 0 on success, errno on error +int AI2cDevice_write(const AI2cDevice* device, const void* data, uint32_t len); + +/// Writes a byte to an I2C register. +/// @param device Pointer to the AI2cDevice struct. +/// @param reg Register to write to. +/// @param val Value to write. +/// @return 0 on success, errno on error +int AI2cDevice_writeRegByte(const AI2cDevice* device, uint8_t reg, uint8_t val); + +/// Writes a word to an I2C register. +/// @param device Pointer to the AI2cDevice struct. +/// @param reg Register to write to. +/// @param val Value to write. +/// @return 0 on success, errno on error +int AI2cDevice_writeRegWord(const AI2cDevice* device, + uint8_t reg, + uint16_t val); + +/// Writes to an I2C register. +/// @param device Pointer to the AI2cDevice struct. +/// @param reg Register to write to. +/// @param data Data to write. +/// @param len Number of bytes to write. +/// @return 0 on success, errno on error +int AI2cDevice_writeRegBuffer(const AI2cDevice* device, + uint8_t reg, + const void* data, + uint32_t len); + +/// Destroys a AI2cDevice struct. +/// @param device Pointer to the AI2cDevice struct. +void AI2cDevice_delete(AI2cDevice* device); + +/// @} + +__END_DECLS + +#endif // SYSTEM_PERIPHERALMANAGER_I2C_DEVICE_H_ diff --git a/pi3-smart-remote/native-libandroidthings-0.5.1-devpreview/armeabi-v7a/include/pio/i2s_device.h b/pi3-smart-remote/native-libandroidthings-0.5.1-devpreview/armeabi-v7a/include/pio/i2s_device.h new file mode 100644 index 0000000..40f27ca --- /dev/null +++ b/pi3-smart-remote/native-libandroidthings-0.5.1-devpreview/armeabi-v7a/include/pio/i2s_device.h @@ -0,0 +1,104 @@ +/* + * Copyright (C) 2017 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef SYSTEM_PERIPHERALMANAGER_I2S_H_ +#define SYSTEM_PERIPHERALMANAGER_I2S_H_ + +#include +#include + +__BEGIN_DECLS + +/// @defgroup I2s I2s Interface +/// @brief Functions to control I2S pins. +/// +/// These functions can be used to control I2S. +/// @{ + +/// Possible encodings +typedef enum AI2sEncoding { + AI2S_ENCODING_PCM_8_BIT, + AI2S_ENCODING_PCM_16_BIT, + AI2S_ENCODING_PCM_24_BIT, + AI2S_ENCODING_PCM_32_BIT +} AI2sEncoding; + +/// Flags to specify I2s bus direction. +typedef enum AI2sFlags { + AI2S_FLAG_DIRECTION_IN = 1 << 0, + AI2S_FLAG_DIRECTION_OUT = 1 << 1 +} AI2sFlags; + +typedef struct AI2sDevice AI2sDevice; + +/// Writes raw data to the I2S device. Multi-channel audio data is interleaved. +/// @param i2s Pointer to the AI2s struct. +/// @param data Data to write. +/// @param offset Offset to first byte in data. +/// @param size Number of bytes to write. +/// @param bytes_written Number of bytes written. +/// @return 0 on success, errno on error. +int AI2sDevice_write(const AI2sDevice* i2s, + const void* data, + int offset, + int size, + int* bytes_written); + +/// Reads raw data from the I2S device. Multi-channel audio data is interleaved. +/// @param i2s Pointer to the AI2s struct. +/// @param data Buffer to fill with data read. +/// @param offset Offset to first byte in data. +/// @param size Number of bytes to read. +/// @param bytes_read Number of bytes read. +/// @return 0 on success, errno on error. +int AI2sDevice_read( + const AI2sDevice* i2s, void* data, int offset, int size, int* bytes_read); + +/// Gets the timestamp when a specific sample entered the kernel. +/// @param i2s Pointer to the AI2s struct. +/// @param frame_position Output indicating number of frames read. +/// @param nano_time Output indicating time (ns) when the frame was read. +/// @param success Output indicating success (1) or failure (0). +/// @return 0 on success, errno on error. This will only be nonzero on a fatal +/// error such as the I2S device couldn't be found; in the normal case +/// that a timestamp isn't available the success param will be used. +int AI2sDevice_getInputTimestamp(const AI2sDevice* i2s, + int64_t* frame_position, + int64_t* nano_time, + int* success); + +/// Gets the timestamp when a specific sample exited the kernel. +/// @param i2s Pointer to the AI2s struct. +/// @param frame_position Output indicating number of frames written. +/// @param nano_time Output indicating time (ns) when the frame was written. +/// @param success Output indicating success (1) or failure (0). +/// @return 0 on success, errno on error. This will only be nonzero on a fatal +/// error such as the I2S device couldn't be found; in the normal case +/// that a timestamp isn't available the success param will be used. +int AI2sDevice_getOutputTimestamp(const AI2sDevice* i2s, + int64_t* frame_position, + int64_t* nano_time, + int* success); + +/// Destroys an AI2s struct. +/// @param i2s Pointer to the AI2s struct. +void AI2sDevice_delete(AI2sDevice* i2s); + +/// @} + +__END_DECLS + +#endif // SYSTEM_PERIPHERALMANAGER_I2S_H_ diff --git a/pi3-smart-remote/native-libandroidthings-0.5.1-devpreview/armeabi-v7a/include/pio/peripheral_manager_client.h b/pi3-smart-remote/native-libandroidthings-0.5.1-devpreview/armeabi-v7a/include/pio/peripheral_manager_client.h new file mode 100644 index 0000000..97202b0 --- /dev/null +++ b/pi3-smart-remote/native-libandroidthings-0.5.1-devpreview/armeabi-v7a/include/pio/peripheral_manager_client.h @@ -0,0 +1,169 @@ +/* + * Copyright (C) 2015 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef SYSTEM_PERIPHERALMANAGER_PERIPHERAL_MANAGER_CLIENT_H_ +#define SYSTEM_PERIPHERALMANAGER_PERIPHERAL_MANAGER_CLIENT_H_ + +#include + +#include "gpio.h" +#include "i2c_device.h" +#include "i2s_device.h" +#include "pwm.h" +#include "spi_device.h" +#include "uart_device.h" + +__BEGIN_DECLS + +/// @defgroup PeripheralManagerClient Peripheral client functions +/// @brief Functions to access embedded peripherals +/// @{ + +typedef struct APeripheralManagerClient APeripheralManagerClient; + +/// Returns the list of GPIOs. +/// This does not take ownership into account. +/// The list must be freed by the caller. +/// @param client Pointer to the APeripheralManagerClient struct. +/// @param num_gpio Output pointer to the number of elements in the list. +/// @return The list of gpios. +char** APeripheralManagerClient_listGpio(const APeripheralManagerClient* client, + int* num_gpio); + +/// Opens a GPIO and takes ownership of it. +/// @param client Pointer to the APeripheralManagerClient struct. +/// @param name Name of the GPIO. +/// @param gpio Output pointer to the AGpio struct. Empty on error. +/// @return 0 on success, errno on error. +int APeripheralManagerClient_openGpio(const APeripheralManagerClient* client, + const char* name, + AGpio** gpio); + +/// Returns the list of PWMs. +/// This does not take ownership into account. +/// The list must be freed by the caller. +/// @param client Pointer to the APeripheralManagerClient struct. +/// @param num_gpio Output pointer to the number of elements in the list. +/// @return The list of pwms. +char** APeripheralManagerClient_listPwm(const APeripheralManagerClient* client, + int* num_pwm); + +/// Opens a PWM and takes ownership of it. +/// @param client Pointer to the APeripheralManagerClient struct. +/// @param name Name of the PWM. +/// @param gpio Output pointer to the AGpio struct. Empty on error. +/// @return 0 on success, errno on error. +int APeripheralManagerClient_openPwm(const APeripheralManagerClient* client, + const char* name, + APwm** pwm); + +/// Returns the list of SPI buses. +/// This does not take ownership into account. +/// The list must be freed by the caller. +/// @param client Pointer to the APeripheralManagerClient struct. +/// @param num_spi_buses Output pointer to the number of elements in the list. +/// @return The list of spi buses. +char** APeripheralManagerClient_listSpiBuses( + const APeripheralManagerClient* client, int* num_spi_buses); + +/// Opens a SPI device and takes ownership of it. +/// @oaram client Pointer to the APeripheralManagerClient struct. +/// @param name Name of the SPI device. +/// @param dev Output pointer to the ASpiDevice struct. Empty on error. +/// @return 0 on success, errno on error. +int APeripheralManagerClient_openSpiDevice( + const APeripheralManagerClient* client, const char* name, ASpiDevice** dev); + +/// Returns the list of I2C buses. +/// This does not take ownership into account. +/// The list must be freed by the caller. +/// @param client Pointer to the APeripheralManagerClient struct. +/// @param num_i2c_buses Output pointer to the number of elements in the list. +/// @return The list of i2c buses. +char** APeripheralManagerClient_listI2cBuses( + const APeripheralManagerClient* client, int* num_i2c_buses); + +/// Opens an I2C device and takes ownership of it. +/// @param client Pointer to the APeripheralManagerClient struct. +/// @param name Name of the I2C bus. +/// @param address Address of the I2C device. +/// @param dev Output pointer to the AI2cDevice struct. Empty on error. +/// @return 0 on success, errno on error +int APeripheralManagerClient_openI2cDevice( + const APeripheralManagerClient* client, + const char* name, + uint32_t address, + AI2cDevice** dev); + +/// Returns the list of UART buses. +/// This does not take ownership into account. +/// The list must be freed by the caller. +/// @param client Pointer to the APeripheralManagerClient struct. +/// @param num_uart_buses Output pointer to the number of elements in the list. +/// @return The list of uart buses. +char** APeripheralManagerClient_listUartDevices( + const APeripheralManagerClient* client, int* num_uart_buses); + +/// Opens an UART device and takes ownership of it. +/// @param client Pointer to the APeripheralManagerClient struct. +/// @param name Name of the UART device. +/// @param dev Output pointer to the AUartDevice struct. Empty on error. +/// @return 0 on success, errno on error +int APeripheralManagerClient_openUartDevice( + const APeripheralManagerClient* client, + const char* name, + AUartDevice** dev); + +/// Returns the list of I2S buses. +/// This does not take ownership into account. +/// The list must be freed by the caller. +/// @param client Pointer to the APeripheralManagerClient struct. +/// @param num_i2s_buses Output pointer to the number of elements in the list. +/// @return The list of I2S buses. +char** APeripheralManagerClient_listI2sDevices( + const APeripheralManagerClient* client, int* num_i2s_buses); + +/// Opens an I2S device and takes ownership of it. +/// @param client Pointer to the APeripheralManagerClient struct. +/// @param name Name of the I2S device. +/// @param encoding Device pcm encoding. +/// @param channels Number of channels. +/// @param rate Device rate in Hz. +/// @param flags Specify device supporting input, output or both. +/// @param dev Output pointer to the AI2sDevice struct. Empty on error. +/// @return 0 on success, errno on error +int APeripheralManagerClient_openI2sDevice( + const APeripheralManagerClient* client, + const char* name, + AI2sEncoding encoding, + int channels, + int rate, + int flags, + AI2sDevice** dev); + +/// Creates a new client. +/// @return A pointer to the created client. nullptr on errors. +APeripheralManagerClient* APeripheralManagerClient_new(); + +/// Destroys the peripheral manager client. +/// @param client Pointer to the APeripheralManagerClient struct. +void APeripheralManagerClient_delete(APeripheralManagerClient* client); + +/// @} + +__END_DECLS + +#endif // SYSTEM_PERIPHERALMANAGER_PERIPHERAL_MANAGER_CLIENT_H_ diff --git a/pi3-smart-remote/native-libandroidthings-0.5.1-devpreview/armeabi-v7a/include/pio/pwm.h b/pi3-smart-remote/native-libandroidthings-0.5.1-devpreview/armeabi-v7a/include/pio/pwm.h new file mode 100644 index 0000000..5dd3a51 --- /dev/null +++ b/pi3-smart-remote/native-libandroidthings-0.5.1-devpreview/armeabi-v7a/include/pio/pwm.h @@ -0,0 +1,59 @@ +/* + * Copyright (C) 2016 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef SYSTEM_PERIPHERALMANAGER_PWM_H_ +#define SYSTEM_PERIPHERALMANAGER_PWM_H_ + +#include +#include + +__BEGIN_DECLS + +/// @defgroup Pwm Pwm Interface +/// @brief Functions to control PWM pins. +/// +/// These functions can be used to control PWM. +/// @{ + +typedef struct APwm APwm; + +/// Sets the PWM duty cycle. +/// @param gpio Pointer to the APwm struct. +/// @param duty_cycle Double between 0 and 100 inclusive. +/// @return 0 on success, errno on error. +int APwm_setDutyCycle(const APwm* pwm, double duty_cycle); + +/// Sets the PWM frequency. +/// @param gpio Pointer to the APwm struct. +/// @param freq Double denoting the frequency in Hz. +/// @return 0 on success, errno on error. +int APwm_setFrequencyHz(const APwm* pwm, double frequency); + +/// Enables the PWM. +/// @param gpio Pointer to the APwm struct. +/// @param enabled Non-zero to enable. +/// @return 0 on success, errno on error. +int APwm_setEnabled(const APwm* pwm, int enabled); + +/// Destroys a APwm struct. +/// @param pwm Pointer to the APwm struct. +void APwm_delete(APwm* pwm); + +/// @} + +__END_DECLS + +#endif // SYSTEM_PERIPHERALMANAGER_PWM_H_ diff --git a/pi3-smart-remote/native-libandroidthings-0.5.1-devpreview/armeabi-v7a/include/pio/spi_device.h b/pi3-smart-remote/native-libandroidthings-0.5.1-devpreview/armeabi-v7a/include/pio/spi_device.h new file mode 100644 index 0000000..51595d7 --- /dev/null +++ b/pi3-smart-remote/native-libandroidthings-0.5.1-devpreview/armeabi-v7a/include/pio/spi_device.h @@ -0,0 +1,119 @@ +/* + * Copyright (C) 2016 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef SYSTEM_PERIPHERALMANAGER_SPI_DEVICE_H_ +#define SYSTEM_PERIPHERALMANAGER_SPI_DEVICE_H_ + +#include +#include + +__BEGIN_DECLS + +/// @defgroup Spi Spi device interface +/// @brief Functions to control an SPI device. +/// +/// These functions can be used to control an SPI device. +/// @{ + +/// Endianness. +typedef enum ASpiBitJustification { + ASPI_LSB_FIRST = 0, /**< Least significant bits first */ + ASPI_MSB_FIRST = 1 /**< Most significant bits first */ +} ASpiBitJustification; + +/// SPI modes (similar to the Linux kernel's modes). +typedef enum ASpiMode { + ASPI_MODE0 = 0, /**< CPHA=0, CPOL=0 */ + ASPI_MODE1 = 1, /**< CPHA=1, CPOL=0 */ + ASPI_MODE2 = 2, /**< CPHA=0, CPOL=1 */ + ASPI_MODE3 = 3 /**< CPHA=1, CPOL=1 */ +} ASpiMode; + +typedef struct ASpiDevice ASpiDevice; + +/// Writes a buffer to the device. +/// @param device Pointer to the ASpiDevice struct. +/// @param data Buffer to write. +/// @param len Length of the buffer. +/// @return 0 on success, errno on error. +int ASpiDevice_writeBuffer(const ASpiDevice* device, + const void* data, + size_t len); + +/// Reads a buffer from the device. +/// @param device Pointer to the ASpiDevice struct. +/// @param data Buffer to read into. +/// @param len Length of the buffer. +/// @return 0 on success, errno on error. +int ASpiDevice_readBuffer(const ASpiDevice* device, void* data, size_t len); + +/// Transfer data to the device. +/// @param device Pointer to the ASpiDevice struct. +/// @param tx_data Buffer to write. +/// @param rx_data Buffer to read data in. If NULL, no data will be read. +/// @param len Length of the buffers. +/// @return 0 on success, errno on error. +int ASpiDevice_transfer(const ASpiDevice* device, + const void* tx_data, + void* rx_data, + size_t len); + +/// Sets the frequency in Hertz. +/// @param device Pointer to the ASpiDevice struct. +/// @param freq_hz Frequency to set. +/// @return 0 on success, errno on error. +int ASpiDevice_setFrequency(const ASpiDevice* device, uint32_t freq_hz); + +/// Sets the SPI mode. +/// @param device Pointer to the ASpiDevice struct. +/// @param mode Mode to use. One of SPI_MODE0, SPI_MODE1, SPI_MODE2, SPI_MODE3. +/// @return 0 on success, errno on error. +int ASpiDevice_setMode(const ASpiDevice* device, ASpiMode mode); + +/// Sets the bit justification. +/// @param device Pointer to the ASpiDevice struct. +/// @param bit_justification One of SPI_LSB_FIRST OR SPI_MSB_FIRST. +/// @return 0 on success, errno on error. +int ASpiDevice_setBitJustification(const ASpiDevice* device, + ASpiBitJustification bit_justification); + +/// Sets the number of bits per words. +/// @param device Pointer to the ASpiDevice struct. +/// @param bits_per_word Number of bits per word. +/// @return 0 on success, errno on error. +int ASpiDevice_setBitsPerWord(const ASpiDevice* device, uint8_t bits_per_word); + +/// Sets the delay to wait after each transfer. +/// @param device Pointer to the ASpiDevice struct. +/// @param delay_usecs Delay in microseconds. +/// @return 0 on success, errno on error. +int ASpiDevice_setDelay(const ASpiDevice* device, uint16_t delay_usecs); + +/// Sets the chip select behavior after each transfer. +/// @param device Pointer to the ASpiDevice struct. +/// @param change If set, cs will be active between transfers. +/// @return 0 on success, errno on error. +int ASpiDevice_setCsChange(const ASpiDevice* device, int change); + +/// Destroys a ASpiDevice struct. +/// @param device Pointer to the ASpiDevice struct. +void ASpiDevice_delete(ASpiDevice* device); + +/// @} + +__END_DECLS + +#endif // SYSTEM_PERIPHERALMANAGER_SPI_DEVICE_H_ diff --git a/pi3-smart-remote/native-libandroidthings-0.5.1-devpreview/armeabi-v7a/include/pio/uart_device.h b/pi3-smart-remote/native-libandroidthings-0.5.1-devpreview/armeabi-v7a/include/pio/uart_device.h new file mode 100644 index 0000000..03ab6d7 --- /dev/null +++ b/pi3-smart-remote/native-libandroidthings-0.5.1-devpreview/armeabi-v7a/include/pio/uart_device.h @@ -0,0 +1,178 @@ +/* + * Copyright (C) 2016 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef SYSTEM_PERIPHERALMANAGER_UART_DEVICE_H_ +#define SYSTEM_PERIPHERALMANAGER_UART_DEVICE_H_ + +#include +#include + +__BEGIN_DECLS + +/// @defgroup Uart Uart device interface +/// @brief Functions to control an UART device. +/// +/// These functions can be used to control an UART device. +/// @{ + +/// UART Parity +typedef enum AUartParity { + AUART_PARITY_NONE = 0, /**< No parity */ + AUART_PARITY_EVEN = 1, /**< Even parity */ + AUART_PARITY_ODD = 2, /**< Odd parity */ + AUART_PARITY_MARK = 3, /**< Mark parity, always 1 */ + AUART_PARITY_SPACE = 4 /**< Space parity, always 0 */ +} AUartParity; + +/// Modem control lines. +typedef enum AUartModemControlLine { + AUART_MODEM_CONTROL_LE = 1 << 0, /**< Data set ready/Line enable */ + AUART_MODEM_CONTROL_DTR = 1 << 1, /**< Data terminal ready */ + AUART_MODEM_CONTROL_RTS = 1 << 2, /**< Request to send */ + AUART_MODEM_CONTROL_ST = 1 << 3, /**< Secondary TXD */ + AUART_MODEM_CONTROL_SR = 1 << 4, /**< Secondary RXD */ + AUART_MODEM_CONTROL_CTS = 1 << 5, /**< Clear to send */ + AUART_MODEM_CONTROL_CD = 1 << 6, /**< Data carrier detect */ + AUART_MODEM_CONTROL_RI = 1 << 7, /**< Ring */ + AUART_MODEM_CONTROL_DSR = 1 << 8 /**< Data set ready */ +} AUartModemControlLine; + +// Hardware Flow Control +typedef enum AUartHardwareFlowControl { + AUART_HARDWARE_FLOW_CONTROL_NONE = 0, /**< No hardware flow control */ + AUART_HARDWARE_FLOW_CONTROL_AUTO_RTSCTS = 1 /**< Auto RTS/CTS */ +} AUartHardwareFlowControl; + +/// Flush queue selection +typedef enum AUartFlushDirection { + AUART_FLUSH_IN = 0, /**< Flushes data received but not read */ + AUART_FLUSH_OUT = 1, /**< Flushes data written but not transmitted */ + AUART_FLUSH_IN_OUT = 2 /**< Flushes both in and out */ +} AUartFlushDirection; + +typedef struct AUartDevice AUartDevice; + +/// Writes to a UART device. +/// @param device Pointer to the AUartDevice struct. +/// @param data Data to write. +/// @param len Size of the data to write. +/// @param bytes_written Output pointer to the number of bytes written. +/// @return 0 on success, errno on error. +int AUartDevice_write(const AUartDevice* device, + const void* data, + uint32_t len, + uint32_t* bytes_written); + +/// Reads from a UART device. +/// @param device Pointer to the AUartDevice struct. +/// @param data Buffer to read the data into. +/// @param len Number of bytes to read. +/// @param bytes_read Output pointer to the number of bytes read. +/// @return 0 on success, errno on error. +int AUartDevice_read(const AUartDevice* device, + void* data, + uint32_t len, + uint32_t* bytes_read); + +/// Sets the input and output speed of a UART device. +/// @param device Pointer to the AUartDevice struct. +/// @param baudrate Speed in baud. +/// @return 0 on success, errno on error. +int AUartDevice_setBaudrate(const AUartDevice* device, uint32_t baudrate); + +/// Sets number of stop bits for the UART device. +/// @param device Pointer to the AUartDevice struct. +/// @param stop_bits Number of stop bits. Typically 1 or 2. +/// @return 0 on success, errno on error. +int AUartDevice_setStopBits(const AUartDevice* device, uint32_t stop_bits); + +/// Sets the data size of a character for the UART device. +/// @param device Pointer to the AUartDevice struct. +/// @param data_size Number of bits per character. Typically between 5 and 8. +/// @return 0 on success, errno on error. +int AUartDevice_setDataSize(const AUartDevice* device, uint32_t data_size); + +/// Sets the parity mode for the UART device. +/// @param device Pointer to the AUartDevice struct. +/// @param mode Parity mode. +/// @return 0 on success, errno on error. +int AUartDevice_setParity(const AUartDevice* device, AUartParity mode); + +/// Sets the hardware flow control mode for the UART device. +/// @param device Pointer to the AUartDevice struct. +/// @param mode Flow control mode. +/// @return 0 on success, errno on error. +int AUartDevice_setHardwareFlowControl(const AUartDevice* device, + AUartHardwareFlowControl mode); + +/// Sets the modem control bits for the UART device. +/// @param device Pointer to the AUartDevice struct. +/// @param lines Lines to set. AUartModemControlLine values OR'ed together. +/// @return 0 on success, errno on error. +int AUartDevice_setModemControl(const AUartDevice* device, uint32_t lines); + +/// Clears the modem control bits for the UART device. +/// @param device Pointer to the AUartDevice struct. +/// @param lines Lines to clear. AUartModemControlLine values OR'ed together. +/// @return 0 on success, errno on error. +int AUartDevice_clearModemControl(const AUartDevice* device, uint32_t lines); + +/// Sends a break to the UART device. +/// @param device Pointer to the AUartDevice struct. +/// @param duration Duration of break transmission in milliseconds. If 0, +/// transmits zero-valued bits for at least 0.25 seconds, and not more +/// than 0.5 seconds. +/// @return 0 on success, errno on error. +int AUartDevice_sendBreak(const AUartDevice* device, uint32_t duration_msecs); + +/// Flushes specified queue for the UART device. +/// @param device Pointer to the AUartDevice struct. +/// @param direction Direction to flush. +/// @return 0 on success, errno on error. +int AUartDevice_flush(const AUartDevice* device, AUartFlushDirection direction); + +/// Gets a file descriptor to be notified when data can be read. +/// +/// You can use this file descriptor to poll on incoming data instead of +/// actively reading for new data. +/// +/// @param device Pointer to the AUartDevice struct. +/// @param fd Output pointer to the file descriptor. +/// @return 0 on success, errno on error. +int AUartDevice_getPollingFd(const AUartDevice* device, int* fd); + +/// Acknowledges an input event. +/// +/// This must be called after receiving an event notification on the polling +/// file descriptor. +/// If you don't acknowledge an event, peripheral manager will assume you are +/// still processing it and you will not receive any more events. +/// If you acknowledge an event before reading the data from the device, you +/// will receive an event immediately as there will still be data available. +/// +/// @param fd File descriptor to acknowledge the event on. +/// @return 0 on success, errno on error. +int AUartDevice_ackInputEvent(int fd); + +/// Destroys a AUartDevice struct. +/// @param device Pointer to the AUartDevice struct. +void AUartDevice_delete(AUartDevice* device); + +/// @} + +__END_DECLS + +#endif // SYSTEM_PERIPHERALMANAGER_UART_DEVICE_H_ diff --git a/pi3-smart-remote/native-libandroidthings-0.5.1-devpreview/armeabi-v7a/lib/libandroidthings.so b/pi3-smart-remote/native-libandroidthings-0.5.1-devpreview/armeabi-v7a/lib/libandroidthings.so new file mode 100644 index 0000000000000000000000000000000000000000..fd485cb4c63a9e13d364d0f8e0f8ac6a604ffdf4 GIT binary patch literal 137764 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 Cr*nn? literal 0 HcmV?d00001 diff --git a/pi3-smart-remote/native-libandroidthings-0.5.1-devpreview/x86/include/pio/gpio.h b/pi3-smart-remote/native-libandroidthings-0.5.1-devpreview/x86/include/pio/gpio.h new file mode 100644 index 0000000..653a4fe --- /dev/null +++ b/pi3-smart-remote/native-libandroidthings-0.5.1-devpreview/x86/include/pio/gpio.h @@ -0,0 +1,107 @@ +/* + * Copyright (C) 2016 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef SYSTEM_PERIPHERALMANAGER_GPIO_H_ +#define SYSTEM_PERIPHERALMANAGER_GPIO_H_ + +#include +#include + +__BEGIN_DECLS + +/// @defgroup Gpio Gpio Interface +/// @brief Functions to control GPIO pins. +/// +/// These functions can be used to control GPIO. +/// @{ + +/// Edge trigger types. +typedef enum AGpioEdge { + AGPIO_EDGE_NONE = 0, /**< None */ + AGPIO_EDGE_RISING = 1, /**< Rising edge */ + AGPIO_EDGE_FALLING = 2, /**< Falling edge */ + AGPIO_EDGE_BOTH = 3 /**< Both edges */ +} AGpioEdge; + +/// GPIO direction types. +typedef enum AGpioDirection { + AGPIO_DIRECTION_IN = 0, /**< Input mode */ + AGPIO_DIRECTION_OUT_INITIALLY_HIGH = 1, /**< Output mode, initially high */ + AGPIO_DIRECTION_OUT_INITIALLY_LOW = 2 /**< Output mode, initially low */ +} AGpioDirection; + +/// Possible active types. +typedef enum AGpioActiveType { + AGPIO_ACTIVE_LOW = 0, /**< Active Low */ + AGPIO_ACTIVE_HIGH = 1 /**< Active High */ +} AGpioActiveType; + +typedef struct AGpio AGpio; + +/// Sets the GPIO direction to output. +/// @param gpio Pointer to the AGpio struct +/// @param direction One of DIRECTION_IN, +/// DIRECTION_OUT_INITIALLY_HIGH, DIRECTION_OUT_INITIALLY_LOW. +/// @return 0 on success, errno on error. +int AGpio_setDirection(const AGpio* gpio, AGpioDirection direction); + +/// Sets the interrupt edge trigger type. +/// @param gpio Pointer to the AGpio struct +/// @param type One of NONE_EDGE, RISING_EDGE, FALLING_EDGE or BOTH_EDGE. +/// @return 0 on success, errno on error. +int AGpio_setEdgeTriggerType(const AGpio* gpio, AGpioEdge type); + +/// Sets the GPIO’s active low/high status. +/// @param gpio Pointer to the AGpio struct. +/// @param type One of ACTIVE_HIGH, ACTIVE_LOW. +/// @return 0 on success, errno on error. +int AGpio_setActiveType(const AGpio* gpio, AGpioActiveType type); + +/// Sets the GPIO value (for output GPIO only). +/// @param gpio Pointer to the AGpio struct. +/// @param value Value to set. +/// @return 0 on success, errno on error. +int AGpio_setValue(const AGpio* gpio, int value); + +/// Gets the GPIO value (for input GPIO only). +/// @param gpio Pointer to the AGpio struct. +/// @param value Output pointer to the value of the GPIO. +/// @return 0 on success, errno on error. +int AGpio_getValue(const AGpio* gpio, int* value); + +/// Returns a file descriptor that can be used to poll on new data. +/// Can be passed to select/epoll to wait for data to become available. +/// @param gpio Pointer to the AGpio struct. +/// @param fd Output pointer to the file descriptor number. +/// @return 0 on success, errno on error. +int AGpio_getPollingFd(const AGpio* gpio, int* fd); + +/// Acknowledges the interrupt and resets the file descriptor. +/// This must be called after each event triggers in order to be able to +/// poll/select for another event. +/// @param fd Polling file descriptor to reset. +/// @return 0 on success, errno on error. +int AGpio_ackInterruptEvent(int fd); + +/// Destroys a AGpio struct. +/// @param gpio Pointer to the AGpio struct. +void AGpio_delete(AGpio* gpio); + +/// @} + +__END_DECLS + +#endif // SYSTEM_PERIPHERALMANAGER_GPIO_H_ diff --git a/pi3-smart-remote/native-libandroidthings-0.5.1-devpreview/x86/include/pio/i2c_device.h b/pi3-smart-remote/native-libandroidthings-0.5.1-devpreview/x86/include/pio/i2c_device.h new file mode 100644 index 0000000..8a5d890 --- /dev/null +++ b/pi3-smart-remote/native-libandroidthings-0.5.1-devpreview/x86/include/pio/i2c_device.h @@ -0,0 +1,109 @@ +/* + * Copyright (C) 2016 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef SYSTEM_PERIPHERALMANAGER_I2C_DEVICE_H_ +#define SYSTEM_PERIPHERALMANAGER_I2C_DEVICE_H_ + +#include +#include + +__BEGIN_DECLS + +/// @defgroup I2c I2c device interface +/// @brief Functions to control an I2C device. +/// +/// These functions can be used to control an I2C device. +/// @{ + +typedef struct AI2cDevice AI2cDevice; + +/// Reads from the device. +/// @param device Pointer to the AI2cDevice struct. +/// @param data Output buffer to write the data to. +/// @param len Number of bytes to read. +/// @return 0 on success, errno on error +int AI2cDevice_read(const AI2cDevice* device, void* data, uint32_t len); + +/// Reads a byte from an I2C register. +/// @param device Pointer to the AI2cDevice struct. +/// @param reg Register to read from. +/// @param val Output pointer to value to read. +/// @return 0 on success, errno on error +int AI2cDevice_readRegByte(const AI2cDevice* device, uint8_t reg, uint8_t* val); + +/// Reads a word from an I2C register. +/// @param device Pointer to the AI2cDevice struct. +/// @param reg Register to read from. +/// @param val Output pointer to value to read. +/// @return 0 on success, errno on error +int AI2cDevice_readRegWord(const AI2cDevice* device, + uint8_t reg, + uint16_t* val); + +/// Reads from an I2C register. +/// @param device Pointer to the AI2cDevice struct. +/// @param reg Register to read from. +/// @param data Output buffer to write the data to. +/// @param len Number of bytes to read. +/// @return 0 on success, errno on error +int AI2cDevice_readRegBuffer(const AI2cDevice* device, + uint8_t reg, + void* data, + uint32_t len); + +/// Writes to the device. +/// @param device Pointer to the AI2cDevice struct. +/// @param data Buffer to write. +/// @param len Number of bytes to write. +/// @return 0 on success, errno on error +int AI2cDevice_write(const AI2cDevice* device, const void* data, uint32_t len); + +/// Writes a byte to an I2C register. +/// @param device Pointer to the AI2cDevice struct. +/// @param reg Register to write to. +/// @param val Value to write. +/// @return 0 on success, errno on error +int AI2cDevice_writeRegByte(const AI2cDevice* device, uint8_t reg, uint8_t val); + +/// Writes a word to an I2C register. +/// @param device Pointer to the AI2cDevice struct. +/// @param reg Register to write to. +/// @param val Value to write. +/// @return 0 on success, errno on error +int AI2cDevice_writeRegWord(const AI2cDevice* device, + uint8_t reg, + uint16_t val); + +/// Writes to an I2C register. +/// @param device Pointer to the AI2cDevice struct. +/// @param reg Register to write to. +/// @param data Data to write. +/// @param len Number of bytes to write. +/// @return 0 on success, errno on error +int AI2cDevice_writeRegBuffer(const AI2cDevice* device, + uint8_t reg, + const void* data, + uint32_t len); + +/// Destroys a AI2cDevice struct. +/// @param device Pointer to the AI2cDevice struct. +void AI2cDevice_delete(AI2cDevice* device); + +/// @} + +__END_DECLS + +#endif // SYSTEM_PERIPHERALMANAGER_I2C_DEVICE_H_ diff --git a/pi3-smart-remote/native-libandroidthings-0.5.1-devpreview/x86/include/pio/i2s_device.h b/pi3-smart-remote/native-libandroidthings-0.5.1-devpreview/x86/include/pio/i2s_device.h new file mode 100644 index 0000000..40f27ca --- /dev/null +++ b/pi3-smart-remote/native-libandroidthings-0.5.1-devpreview/x86/include/pio/i2s_device.h @@ -0,0 +1,104 @@ +/* + * Copyright (C) 2017 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef SYSTEM_PERIPHERALMANAGER_I2S_H_ +#define SYSTEM_PERIPHERALMANAGER_I2S_H_ + +#include +#include + +__BEGIN_DECLS + +/// @defgroup I2s I2s Interface +/// @brief Functions to control I2S pins. +/// +/// These functions can be used to control I2S. +/// @{ + +/// Possible encodings +typedef enum AI2sEncoding { + AI2S_ENCODING_PCM_8_BIT, + AI2S_ENCODING_PCM_16_BIT, + AI2S_ENCODING_PCM_24_BIT, + AI2S_ENCODING_PCM_32_BIT +} AI2sEncoding; + +/// Flags to specify I2s bus direction. +typedef enum AI2sFlags { + AI2S_FLAG_DIRECTION_IN = 1 << 0, + AI2S_FLAG_DIRECTION_OUT = 1 << 1 +} AI2sFlags; + +typedef struct AI2sDevice AI2sDevice; + +/// Writes raw data to the I2S device. Multi-channel audio data is interleaved. +/// @param i2s Pointer to the AI2s struct. +/// @param data Data to write. +/// @param offset Offset to first byte in data. +/// @param size Number of bytes to write. +/// @param bytes_written Number of bytes written. +/// @return 0 on success, errno on error. +int AI2sDevice_write(const AI2sDevice* i2s, + const void* data, + int offset, + int size, + int* bytes_written); + +/// Reads raw data from the I2S device. Multi-channel audio data is interleaved. +/// @param i2s Pointer to the AI2s struct. +/// @param data Buffer to fill with data read. +/// @param offset Offset to first byte in data. +/// @param size Number of bytes to read. +/// @param bytes_read Number of bytes read. +/// @return 0 on success, errno on error. +int AI2sDevice_read( + const AI2sDevice* i2s, void* data, int offset, int size, int* bytes_read); + +/// Gets the timestamp when a specific sample entered the kernel. +/// @param i2s Pointer to the AI2s struct. +/// @param frame_position Output indicating number of frames read. +/// @param nano_time Output indicating time (ns) when the frame was read. +/// @param success Output indicating success (1) or failure (0). +/// @return 0 on success, errno on error. This will only be nonzero on a fatal +/// error such as the I2S device couldn't be found; in the normal case +/// that a timestamp isn't available the success param will be used. +int AI2sDevice_getInputTimestamp(const AI2sDevice* i2s, + int64_t* frame_position, + int64_t* nano_time, + int* success); + +/// Gets the timestamp when a specific sample exited the kernel. +/// @param i2s Pointer to the AI2s struct. +/// @param frame_position Output indicating number of frames written. +/// @param nano_time Output indicating time (ns) when the frame was written. +/// @param success Output indicating success (1) or failure (0). +/// @return 0 on success, errno on error. This will only be nonzero on a fatal +/// error such as the I2S device couldn't be found; in the normal case +/// that a timestamp isn't available the success param will be used. +int AI2sDevice_getOutputTimestamp(const AI2sDevice* i2s, + int64_t* frame_position, + int64_t* nano_time, + int* success); + +/// Destroys an AI2s struct. +/// @param i2s Pointer to the AI2s struct. +void AI2sDevice_delete(AI2sDevice* i2s); + +/// @} + +__END_DECLS + +#endif // SYSTEM_PERIPHERALMANAGER_I2S_H_ diff --git a/pi3-smart-remote/native-libandroidthings-0.5.1-devpreview/x86/include/pio/peripheral_manager_client.h b/pi3-smart-remote/native-libandroidthings-0.5.1-devpreview/x86/include/pio/peripheral_manager_client.h new file mode 100644 index 0000000..97202b0 --- /dev/null +++ b/pi3-smart-remote/native-libandroidthings-0.5.1-devpreview/x86/include/pio/peripheral_manager_client.h @@ -0,0 +1,169 @@ +/* + * Copyright (C) 2015 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef SYSTEM_PERIPHERALMANAGER_PERIPHERAL_MANAGER_CLIENT_H_ +#define SYSTEM_PERIPHERALMANAGER_PERIPHERAL_MANAGER_CLIENT_H_ + +#include + +#include "gpio.h" +#include "i2c_device.h" +#include "i2s_device.h" +#include "pwm.h" +#include "spi_device.h" +#include "uart_device.h" + +__BEGIN_DECLS + +/// @defgroup PeripheralManagerClient Peripheral client functions +/// @brief Functions to access embedded peripherals +/// @{ + +typedef struct APeripheralManagerClient APeripheralManagerClient; + +/// Returns the list of GPIOs. +/// This does not take ownership into account. +/// The list must be freed by the caller. +/// @param client Pointer to the APeripheralManagerClient struct. +/// @param num_gpio Output pointer to the number of elements in the list. +/// @return The list of gpios. +char** APeripheralManagerClient_listGpio(const APeripheralManagerClient* client, + int* num_gpio); + +/// Opens a GPIO and takes ownership of it. +/// @param client Pointer to the APeripheralManagerClient struct. +/// @param name Name of the GPIO. +/// @param gpio Output pointer to the AGpio struct. Empty on error. +/// @return 0 on success, errno on error. +int APeripheralManagerClient_openGpio(const APeripheralManagerClient* client, + const char* name, + AGpio** gpio); + +/// Returns the list of PWMs. +/// This does not take ownership into account. +/// The list must be freed by the caller. +/// @param client Pointer to the APeripheralManagerClient struct. +/// @param num_gpio Output pointer to the number of elements in the list. +/// @return The list of pwms. +char** APeripheralManagerClient_listPwm(const APeripheralManagerClient* client, + int* num_pwm); + +/// Opens a PWM and takes ownership of it. +/// @param client Pointer to the APeripheralManagerClient struct. +/// @param name Name of the PWM. +/// @param gpio Output pointer to the AGpio struct. Empty on error. +/// @return 0 on success, errno on error. +int APeripheralManagerClient_openPwm(const APeripheralManagerClient* client, + const char* name, + APwm** pwm); + +/// Returns the list of SPI buses. +/// This does not take ownership into account. +/// The list must be freed by the caller. +/// @param client Pointer to the APeripheralManagerClient struct. +/// @param num_spi_buses Output pointer to the number of elements in the list. +/// @return The list of spi buses. +char** APeripheralManagerClient_listSpiBuses( + const APeripheralManagerClient* client, int* num_spi_buses); + +/// Opens a SPI device and takes ownership of it. +/// @oaram client Pointer to the APeripheralManagerClient struct. +/// @param name Name of the SPI device. +/// @param dev Output pointer to the ASpiDevice struct. Empty on error. +/// @return 0 on success, errno on error. +int APeripheralManagerClient_openSpiDevice( + const APeripheralManagerClient* client, const char* name, ASpiDevice** dev); + +/// Returns the list of I2C buses. +/// This does not take ownership into account. +/// The list must be freed by the caller. +/// @param client Pointer to the APeripheralManagerClient struct. +/// @param num_i2c_buses Output pointer to the number of elements in the list. +/// @return The list of i2c buses. +char** APeripheralManagerClient_listI2cBuses( + const APeripheralManagerClient* client, int* num_i2c_buses); + +/// Opens an I2C device and takes ownership of it. +/// @param client Pointer to the APeripheralManagerClient struct. +/// @param name Name of the I2C bus. +/// @param address Address of the I2C device. +/// @param dev Output pointer to the AI2cDevice struct. Empty on error. +/// @return 0 on success, errno on error +int APeripheralManagerClient_openI2cDevice( + const APeripheralManagerClient* client, + const char* name, + uint32_t address, + AI2cDevice** dev); + +/// Returns the list of UART buses. +/// This does not take ownership into account. +/// The list must be freed by the caller. +/// @param client Pointer to the APeripheralManagerClient struct. +/// @param num_uart_buses Output pointer to the number of elements in the list. +/// @return The list of uart buses. +char** APeripheralManagerClient_listUartDevices( + const APeripheralManagerClient* client, int* num_uart_buses); + +/// Opens an UART device and takes ownership of it. +/// @param client Pointer to the APeripheralManagerClient struct. +/// @param name Name of the UART device. +/// @param dev Output pointer to the AUartDevice struct. Empty on error. +/// @return 0 on success, errno on error +int APeripheralManagerClient_openUartDevice( + const APeripheralManagerClient* client, + const char* name, + AUartDevice** dev); + +/// Returns the list of I2S buses. +/// This does not take ownership into account. +/// The list must be freed by the caller. +/// @param client Pointer to the APeripheralManagerClient struct. +/// @param num_i2s_buses Output pointer to the number of elements in the list. +/// @return The list of I2S buses. +char** APeripheralManagerClient_listI2sDevices( + const APeripheralManagerClient* client, int* num_i2s_buses); + +/// Opens an I2S device and takes ownership of it. +/// @param client Pointer to the APeripheralManagerClient struct. +/// @param name Name of the I2S device. +/// @param encoding Device pcm encoding. +/// @param channels Number of channels. +/// @param rate Device rate in Hz. +/// @param flags Specify device supporting input, output or both. +/// @param dev Output pointer to the AI2sDevice struct. Empty on error. +/// @return 0 on success, errno on error +int APeripheralManagerClient_openI2sDevice( + const APeripheralManagerClient* client, + const char* name, + AI2sEncoding encoding, + int channels, + int rate, + int flags, + AI2sDevice** dev); + +/// Creates a new client. +/// @return A pointer to the created client. nullptr on errors. +APeripheralManagerClient* APeripheralManagerClient_new(); + +/// Destroys the peripheral manager client. +/// @param client Pointer to the APeripheralManagerClient struct. +void APeripheralManagerClient_delete(APeripheralManagerClient* client); + +/// @} + +__END_DECLS + +#endif // SYSTEM_PERIPHERALMANAGER_PERIPHERAL_MANAGER_CLIENT_H_ diff --git a/pi3-smart-remote/native-libandroidthings-0.5.1-devpreview/x86/include/pio/pwm.h b/pi3-smart-remote/native-libandroidthings-0.5.1-devpreview/x86/include/pio/pwm.h new file mode 100644 index 0000000..5dd3a51 --- /dev/null +++ b/pi3-smart-remote/native-libandroidthings-0.5.1-devpreview/x86/include/pio/pwm.h @@ -0,0 +1,59 @@ +/* + * Copyright (C) 2016 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef SYSTEM_PERIPHERALMANAGER_PWM_H_ +#define SYSTEM_PERIPHERALMANAGER_PWM_H_ + +#include +#include + +__BEGIN_DECLS + +/// @defgroup Pwm Pwm Interface +/// @brief Functions to control PWM pins. +/// +/// These functions can be used to control PWM. +/// @{ + +typedef struct APwm APwm; + +/// Sets the PWM duty cycle. +/// @param gpio Pointer to the APwm struct. +/// @param duty_cycle Double between 0 and 100 inclusive. +/// @return 0 on success, errno on error. +int APwm_setDutyCycle(const APwm* pwm, double duty_cycle); + +/// Sets the PWM frequency. +/// @param gpio Pointer to the APwm struct. +/// @param freq Double denoting the frequency in Hz. +/// @return 0 on success, errno on error. +int APwm_setFrequencyHz(const APwm* pwm, double frequency); + +/// Enables the PWM. +/// @param gpio Pointer to the APwm struct. +/// @param enabled Non-zero to enable. +/// @return 0 on success, errno on error. +int APwm_setEnabled(const APwm* pwm, int enabled); + +/// Destroys a APwm struct. +/// @param pwm Pointer to the APwm struct. +void APwm_delete(APwm* pwm); + +/// @} + +__END_DECLS + +#endif // SYSTEM_PERIPHERALMANAGER_PWM_H_ diff --git a/pi3-smart-remote/native-libandroidthings-0.5.1-devpreview/x86/include/pio/spi_device.h b/pi3-smart-remote/native-libandroidthings-0.5.1-devpreview/x86/include/pio/spi_device.h new file mode 100644 index 0000000..51595d7 --- /dev/null +++ b/pi3-smart-remote/native-libandroidthings-0.5.1-devpreview/x86/include/pio/spi_device.h @@ -0,0 +1,119 @@ +/* + * Copyright (C) 2016 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef SYSTEM_PERIPHERALMANAGER_SPI_DEVICE_H_ +#define SYSTEM_PERIPHERALMANAGER_SPI_DEVICE_H_ + +#include +#include + +__BEGIN_DECLS + +/// @defgroup Spi Spi device interface +/// @brief Functions to control an SPI device. +/// +/// These functions can be used to control an SPI device. +/// @{ + +/// Endianness. +typedef enum ASpiBitJustification { + ASPI_LSB_FIRST = 0, /**< Least significant bits first */ + ASPI_MSB_FIRST = 1 /**< Most significant bits first */ +} ASpiBitJustification; + +/// SPI modes (similar to the Linux kernel's modes). +typedef enum ASpiMode { + ASPI_MODE0 = 0, /**< CPHA=0, CPOL=0 */ + ASPI_MODE1 = 1, /**< CPHA=1, CPOL=0 */ + ASPI_MODE2 = 2, /**< CPHA=0, CPOL=1 */ + ASPI_MODE3 = 3 /**< CPHA=1, CPOL=1 */ +} ASpiMode; + +typedef struct ASpiDevice ASpiDevice; + +/// Writes a buffer to the device. +/// @param device Pointer to the ASpiDevice struct. +/// @param data Buffer to write. +/// @param len Length of the buffer. +/// @return 0 on success, errno on error. +int ASpiDevice_writeBuffer(const ASpiDevice* device, + const void* data, + size_t len); + +/// Reads a buffer from the device. +/// @param device Pointer to the ASpiDevice struct. +/// @param data Buffer to read into. +/// @param len Length of the buffer. +/// @return 0 on success, errno on error. +int ASpiDevice_readBuffer(const ASpiDevice* device, void* data, size_t len); + +/// Transfer data to the device. +/// @param device Pointer to the ASpiDevice struct. +/// @param tx_data Buffer to write. +/// @param rx_data Buffer to read data in. If NULL, no data will be read. +/// @param len Length of the buffers. +/// @return 0 on success, errno on error. +int ASpiDevice_transfer(const ASpiDevice* device, + const void* tx_data, + void* rx_data, + size_t len); + +/// Sets the frequency in Hertz. +/// @param device Pointer to the ASpiDevice struct. +/// @param freq_hz Frequency to set. +/// @return 0 on success, errno on error. +int ASpiDevice_setFrequency(const ASpiDevice* device, uint32_t freq_hz); + +/// Sets the SPI mode. +/// @param device Pointer to the ASpiDevice struct. +/// @param mode Mode to use. One of SPI_MODE0, SPI_MODE1, SPI_MODE2, SPI_MODE3. +/// @return 0 on success, errno on error. +int ASpiDevice_setMode(const ASpiDevice* device, ASpiMode mode); + +/// Sets the bit justification. +/// @param device Pointer to the ASpiDevice struct. +/// @param bit_justification One of SPI_LSB_FIRST OR SPI_MSB_FIRST. +/// @return 0 on success, errno on error. +int ASpiDevice_setBitJustification(const ASpiDevice* device, + ASpiBitJustification bit_justification); + +/// Sets the number of bits per words. +/// @param device Pointer to the ASpiDevice struct. +/// @param bits_per_word Number of bits per word. +/// @return 0 on success, errno on error. +int ASpiDevice_setBitsPerWord(const ASpiDevice* device, uint8_t bits_per_word); + +/// Sets the delay to wait after each transfer. +/// @param device Pointer to the ASpiDevice struct. +/// @param delay_usecs Delay in microseconds. +/// @return 0 on success, errno on error. +int ASpiDevice_setDelay(const ASpiDevice* device, uint16_t delay_usecs); + +/// Sets the chip select behavior after each transfer. +/// @param device Pointer to the ASpiDevice struct. +/// @param change If set, cs will be active between transfers. +/// @return 0 on success, errno on error. +int ASpiDevice_setCsChange(const ASpiDevice* device, int change); + +/// Destroys a ASpiDevice struct. +/// @param device Pointer to the ASpiDevice struct. +void ASpiDevice_delete(ASpiDevice* device); + +/// @} + +__END_DECLS + +#endif // SYSTEM_PERIPHERALMANAGER_SPI_DEVICE_H_ diff --git a/pi3-smart-remote/native-libandroidthings-0.5.1-devpreview/x86/include/pio/uart_device.h b/pi3-smart-remote/native-libandroidthings-0.5.1-devpreview/x86/include/pio/uart_device.h new file mode 100644 index 0000000..03ab6d7 --- /dev/null +++ b/pi3-smart-remote/native-libandroidthings-0.5.1-devpreview/x86/include/pio/uart_device.h @@ -0,0 +1,178 @@ +/* + * Copyright (C) 2016 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef SYSTEM_PERIPHERALMANAGER_UART_DEVICE_H_ +#define SYSTEM_PERIPHERALMANAGER_UART_DEVICE_H_ + +#include +#include + +__BEGIN_DECLS + +/// @defgroup Uart Uart device interface +/// @brief Functions to control an UART device. +/// +/// These functions can be used to control an UART device. +/// @{ + +/// UART Parity +typedef enum AUartParity { + AUART_PARITY_NONE = 0, /**< No parity */ + AUART_PARITY_EVEN = 1, /**< Even parity */ + AUART_PARITY_ODD = 2, /**< Odd parity */ + AUART_PARITY_MARK = 3, /**< Mark parity, always 1 */ + AUART_PARITY_SPACE = 4 /**< Space parity, always 0 */ +} AUartParity; + +/// Modem control lines. +typedef enum AUartModemControlLine { + AUART_MODEM_CONTROL_LE = 1 << 0, /**< Data set ready/Line enable */ + AUART_MODEM_CONTROL_DTR = 1 << 1, /**< Data terminal ready */ + AUART_MODEM_CONTROL_RTS = 1 << 2, /**< Request to send */ + AUART_MODEM_CONTROL_ST = 1 << 3, /**< Secondary TXD */ + AUART_MODEM_CONTROL_SR = 1 << 4, /**< Secondary RXD */ + AUART_MODEM_CONTROL_CTS = 1 << 5, /**< Clear to send */ + AUART_MODEM_CONTROL_CD = 1 << 6, /**< Data carrier detect */ + AUART_MODEM_CONTROL_RI = 1 << 7, /**< Ring */ + AUART_MODEM_CONTROL_DSR = 1 << 8 /**< Data set ready */ +} AUartModemControlLine; + +// Hardware Flow Control +typedef enum AUartHardwareFlowControl { + AUART_HARDWARE_FLOW_CONTROL_NONE = 0, /**< No hardware flow control */ + AUART_HARDWARE_FLOW_CONTROL_AUTO_RTSCTS = 1 /**< Auto RTS/CTS */ +} AUartHardwareFlowControl; + +/// Flush queue selection +typedef enum AUartFlushDirection { + AUART_FLUSH_IN = 0, /**< Flushes data received but not read */ + AUART_FLUSH_OUT = 1, /**< Flushes data written but not transmitted */ + AUART_FLUSH_IN_OUT = 2 /**< Flushes both in and out */ +} AUartFlushDirection; + +typedef struct AUartDevice AUartDevice; + +/// Writes to a UART device. +/// @param device Pointer to the AUartDevice struct. +/// @param data Data to write. +/// @param len Size of the data to write. +/// @param bytes_written Output pointer to the number of bytes written. +/// @return 0 on success, errno on error. +int AUartDevice_write(const AUartDevice* device, + const void* data, + uint32_t len, + uint32_t* bytes_written); + +/// Reads from a UART device. +/// @param device Pointer to the AUartDevice struct. +/// @param data Buffer to read the data into. +/// @param len Number of bytes to read. +/// @param bytes_read Output pointer to the number of bytes read. +/// @return 0 on success, errno on error. +int AUartDevice_read(const AUartDevice* device, + void* data, + uint32_t len, + uint32_t* bytes_read); + +/// Sets the input and output speed of a UART device. +/// @param device Pointer to the AUartDevice struct. +/// @param baudrate Speed in baud. +/// @return 0 on success, errno on error. +int AUartDevice_setBaudrate(const AUartDevice* device, uint32_t baudrate); + +/// Sets number of stop bits for the UART device. +/// @param device Pointer to the AUartDevice struct. +/// @param stop_bits Number of stop bits. Typically 1 or 2. +/// @return 0 on success, errno on error. +int AUartDevice_setStopBits(const AUartDevice* device, uint32_t stop_bits); + +/// Sets the data size of a character for the UART device. +/// @param device Pointer to the AUartDevice struct. +/// @param data_size Number of bits per character. Typically between 5 and 8. +/// @return 0 on success, errno on error. +int AUartDevice_setDataSize(const AUartDevice* device, uint32_t data_size); + +/// Sets the parity mode for the UART device. +/// @param device Pointer to the AUartDevice struct. +/// @param mode Parity mode. +/// @return 0 on success, errno on error. +int AUartDevice_setParity(const AUartDevice* device, AUartParity mode); + +/// Sets the hardware flow control mode for the UART device. +/// @param device Pointer to the AUartDevice struct. +/// @param mode Flow control mode. +/// @return 0 on success, errno on error. +int AUartDevice_setHardwareFlowControl(const AUartDevice* device, + AUartHardwareFlowControl mode); + +/// Sets the modem control bits for the UART device. +/// @param device Pointer to the AUartDevice struct. +/// @param lines Lines to set. AUartModemControlLine values OR'ed together. +/// @return 0 on success, errno on error. +int AUartDevice_setModemControl(const AUartDevice* device, uint32_t lines); + +/// Clears the modem control bits for the UART device. +/// @param device Pointer to the AUartDevice struct. +/// @param lines Lines to clear. AUartModemControlLine values OR'ed together. +/// @return 0 on success, errno on error. +int AUartDevice_clearModemControl(const AUartDevice* device, uint32_t lines); + +/// Sends a break to the UART device. +/// @param device Pointer to the AUartDevice struct. +/// @param duration Duration of break transmission in milliseconds. If 0, +/// transmits zero-valued bits for at least 0.25 seconds, and not more +/// than 0.5 seconds. +/// @return 0 on success, errno on error. +int AUartDevice_sendBreak(const AUartDevice* device, uint32_t duration_msecs); + +/// Flushes specified queue for the UART device. +/// @param device Pointer to the AUartDevice struct. +/// @param direction Direction to flush. +/// @return 0 on success, errno on error. +int AUartDevice_flush(const AUartDevice* device, AUartFlushDirection direction); + +/// Gets a file descriptor to be notified when data can be read. +/// +/// You can use this file descriptor to poll on incoming data instead of +/// actively reading for new data. +/// +/// @param device Pointer to the AUartDevice struct. +/// @param fd Output pointer to the file descriptor. +/// @return 0 on success, errno on error. +int AUartDevice_getPollingFd(const AUartDevice* device, int* fd); + +/// Acknowledges an input event. +/// +/// This must be called after receiving an event notification on the polling +/// file descriptor. +/// If you don't acknowledge an event, peripheral manager will assume you are +/// still processing it and you will not receive any more events. +/// If you acknowledge an event before reading the data from the device, you +/// will receive an event immediately as there will still be data available. +/// +/// @param fd File descriptor to acknowledge the event on. +/// @return 0 on success, errno on error. +int AUartDevice_ackInputEvent(int fd); + +/// Destroys a AUartDevice struct. +/// @param device Pointer to the AUartDevice struct. +void AUartDevice_delete(AUartDevice* device); + +/// @} + +__END_DECLS + +#endif // SYSTEM_PERIPHERALMANAGER_UART_DEVICE_H_ diff --git a/pi3-smart-remote/native-libandroidthings-0.5.1-devpreview/x86/lib/libandroidthings.so b/pi3-smart-remote/native-libandroidthings-0.5.1-devpreview/x86/lib/libandroidthings.so new file mode 100644 index 0000000000000000000000000000000000000000..1ff0285545790922e29eb84adfdbead9ee8c70b8 GIT binary patch literal 190916 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 z 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